[successivo] [precedente] [inizio] [fine] [indice generale] [violazione GPL] [translators] [docinfo] [indice analitico] [volume] [parte]
Un servizio molto importante che può offrire un servente è la copia di informazioni già accessibili attraverso la rete. Il vantaggio di creare un sito speculare, ovvero un mirror, sta nel ridurre la concentrazione di richieste in una sola origine. Questo si riflette positivamente sia negli utenti locali, che ottengono le informazioni più rapidamente e con meno probabilità di essere esclusi per motivi di affollamento, sia nel servizio di origine, per il minore impegno richiesto al nodo e per il minore utilizzo della banda di collegamento alla rete.
In altre situazioni, quando gli utenti di una rete privata non hanno accesso all'esterno, la creazione di un sito speculare raggiungibile da questi utenti è l'unica possibilità per loro di ottenere tali informazioni.
L'utilizzatore normale dei servizi di Internet può non comprendere la differenza che c'è tra l'accedere a un servizio FTP rispetto a un altro, quando questi sono identici. La netiquette dice di usare il servizio più vicino, ma finché non si comprende il motivo è difficile che questa regola (come altre) venga rispettata.
Internet è fatta di tanti segmenti che collegano i vari nodi di rete, o host. I segmenti sono i cavi per i quali deve essere pagato un affitto all'azienda che può offrire tale servizio (in base alle norme dei rispettivi paesi). Ciò si traduce generalmente in un costo fisso, per il solo fatto di utilizzare il cavo, sia che vengano trasferiti dati, sia che resti semplicemente lì a disposizione.(1)
Tuttavia, anche se si tratta di un costo fisso, quando su quel cavo passano dei pacchetti non ne possono passare degli altri, ovvero, un flusso di dati rallenta il passaggio di altri dati.
Quando si ha la necessità di prelevare dalla rete grandi quantità di dati, tipicamente attraverso il protocollo FTP, è opportuno, in tutti i sensi, di cercare la fonte più vicina. La distanza in questione non si valuta in base a uno spazio geografico, ma attraverso il numero di salti che i pacchetti devono fare, cioè il numero di nodi attraverso cui devono transitare. Minore è il numero di salti, minore sarà il numero di segmenti da utilizzare e così anche minore il costo per la comunità Internet. Questo dovrebbe chiarire anche l'utilità della presenza dei siti speculari nella rete.
Quando un servizio per il quale si predispongono dei siti speculari diviene molto importante e si vogliono realizzare molte di queste copie, si può porre il problema di non affollare il servizio di origine nel momento in cui i vari siti devono essere aggiornati.
Per risolvere questo problema conviene scomporre il sistema in più livelli: un punto di origine; alcuni siti speculari di primo livello (o primari); altri siti speculari che dipendono da quelli primari.
|
I siti speculari sono utili in quanto contenenti una copia identica delle informazioni di loro competenza. L'allineamento, o sincronizzazione, avviene attraverso un controllo periodico e il trasferimento dei dati variati. Questa operazione non può essere fatta in modo continuo; si tratta di un lavoro di routine, da eseguire periodicamente a intervalli regolari.
La scelta della lunghezza di questi intervalli e del momento in cui eseguire questa attività è molto importante. In generale è bene definire che questo lavoro di sincronizzazione non può essere svolto ragionevolmente più di una volta nell'arco delle 24 ore, perché si tradurrebbe in un carico ingiustificato per il nodo dal quale si vogliono ottenere i dati. Dall'altra parte, l'orario in cui si eseguono queste operazioni dovrebbe essere scelto in modo da non interferire con altre attività, quindi nel momento di minore carico, sia per il nodo a cui ci si collega, sia per quello all'interno del quale si esegue la riproduzione speculare.
Mirror (2) è un programma scritto in Perl che, attraverso il protocollo FTP, permette di duplicare una gerarchia di directory presente in un nodo remoto all'interno di quello locale. Il suo scopo è (ovviamente) quello di evitare la copia di file già presenti e ritenuti aggiornati. Per ottenere questo, viene comparata la data e la dimensione dei file.
Le fasi attraverso cui Mirror compie il suo lavoro possono essere schematizzate nei punti seguenti:
contatta il sistema remoto;
prepara un elenco dei file e directory esistenti a partire dal punto di destinazione locale;
prepara un elenco dei file e directory esistenti a partire dal punto di origine del sistema remoto;
confronta i due elenchi;
crea le sottodirectory necessarie;
trasferisce i file necessari;
elimina file e directory non più necessari;
termina la connessione.
Mirror può essere usato fondamentalmente in due modi: fornendo tutte le informazioni necessarie attraverso la riga di comando (sconsigliabile) o configurando il file mirror.defaults
. La scelta di impostare Mirror attraverso il suo file di configurazione è decisamente preferibile, dal momento che all'interno dello stesso possono essere indicate impostazioni differenti riferite a diversi «pacchetti» da replicare. In pratica, con questo termine (pacchetto), si intende fare riferimento a un blocco di dati da replicare nel sistema locale. Attraverso la riga di comando ci si può limitare a specificare il pacchetto o i pacchetti da sincronizzare.
Utilizzando Mirror, quando si deve indicare un percorso che fa riferimento a una directory e non a un file normale, è bene aggiungere la barra obliqua finale (/) per evitare ambiguità. |
mirror [opzioni] -gindirizzo:percorso
mirror [opzioni] [file_di_configurazione]
L'eseguibile mirror è ciò che svolge tutto il lavoro. Il suo scopo è quello di duplicare e mantenere sincronizzata una copia di una directory remota, attraverso il protocollo FTP. Le due sintassi rappresentate esprimono due modi differenti di utilizzo del programma: nel primo caso si indica il nodo e la directory remota direttamente sulla riga di comando, intendendo probabilmente che quella deve essere duplicata nel sistema locale a partire dalla directory corrente, nel secondo ci si avvale di un file di configurazione, più utile per l'utilizzo sistematico.
Il file di configurazione in questione può essere quello predefinito, mirror.defaults
, che dovrebbe trovarsi nella stessa directory del programma (è bene ricordare che il programma è uno script Perl e la sua collocazione non corrisponde a quella dei binari normali). Generalmente, per questioni di compatibilità con la gerarchia del file system standard dei sistemi GNU, si colloca questo file nella directory /etc/
, mettendo un collegamento simbolico opportuno nella posizione in cui Mirror si aspetta di trovarlo.
Segue la descrizione di alcuni esempi.
#
mirror -ptulipano
Avvia Mirror in modo che esegua la duplicazione o l'allineamento di quanto indicato all'interno del pacchetto tulipano definito all'interno del file di configurazione.
$
mirror -gdinkel.brot.dg:/pub/documenti/tulipano/
Avvia Mirror senza usare il file di configurazione, specificando che si vuole duplicare o allineare la directory ftp://dinkel.brot.dg/pub/documenti/tulipano/
con quella corrente (del nodo locale) nel momento in cui si avvia il programma.
Come si vede, l'utente che esegue l'operazione non è root, quindi i file vengono trasferiti attribuendo loro la proprietà dell'utente che esegue il comando. In questo caso, è più probabile che debba essere indicato il percorso necessario ad avviare l'eseguibile mirror.
Il file mirror.defaults
è il mezzo normale per dirigere il comportamento di Mirror. Se l'installazione di Mirror è stata fatta correttamente e opportunamente, la sua collocazione dovrebbe essere la directory /etc/
.
Il file si suddivide in configurazioni riferite a «pacchetti» differenti a cui si può fare riferimento utilizzando l'opzione -p.
Generalmente, questo file viene fornito con la configurazione per il pacchetto defaults. La configurazione corrispondente viene trattata come quella predefinita e va a sovrapporsi alle definizioni predefinite di Mirror stesso. In tal senso è opportuno verificare queste definizioni ed eventualmente modificarle, anche se per gli usi normali non dovrebbe essere necessario.
Quello che segue è un esempio del file mirror.defaults
con la sola definizione di un pacchetto default, molto più breve di quello che viene distribuito assieme all'applicativo.
# Il pacchetto «defaults» permette di definire una configurazione # predefinita diversa da quella normale del programma mirror. package=defaults local_dir=/home/ftp/pub/ dir_mode=0755 file_mode=0444 user=0 group=0 do_deletes=true max_delete_files=50% max_delete_dirs=50% |
Per prima cosa si osserva che i commenti sono prefissati dal simbolo # e che le righe vuote non vengono prese in considerazione.
Le direttive di questo file sono rappresentate da semplici assegnamenti di variabili, nella forma nome=valore. Tutto ciò che appare dopo il segno di uguaglianza viene «inserito» nella variabile indicata alla sinistra. Non si usano delimitatori, per cui, se si lasciano spazi dopo il simbolo di uguaglianza, questi verranno inseriti, tali e quali. Sono ammissibili anche assegnamenti nella forma nome+valore, in tal caso, ciò che appare alla destra del segno + viene aggiunto al contenuto della variabile.
Se esiste la necessità di spezzare una direttiva per riprenderla nella riga successiva, si può usare il simbolo e-commerciale (&) alla fine della riga che poi deve essere ripresa. La riga successiva verrà attaccata a quella precedente eliminando gli spazi anteriori (in tal modo si possono incolonnare i dati senza inconvenienti).
Gli elenchi di direttive sono raggruppati in «pacchetti» in cui la prima direttiva è sempre package=.... Nell'esempio questa direttiva viene mostrata allineata diversamente dalle altre, proprio per fare risaltare visivamente il suo ruolo importante.
Segue la descrizione di alcuni esempi di configurazione.
package=prova site=localhost remote_dir=/pub/ local_dir=/tmp/prova/ do_deletes=true max_delete_files=100% max_delete_dirs=100% update_log=/tmp/prova.log |
L'esempio mostra un «pacchetto» definito solo per provare a eseguire la riproduzione speculare di quanto disponibile a partire da ftp://localhost/pub/
, collocandolo nella directory /tmp/prova/
. Se la directory di destinazione non esiste, questa viene creata.
Inoltre: è concessa la cancellazione dei file che non si trovano più nell'origine; la cancellazione è concessa fino al massimo del 100 %, sia per i file che per le directory; il file utilizzato per registrare le operazioni è /tmp/prova.log
.
Per eseguire la riproduzione speculare nel modo specificato dal pacchetto prova si può utilizzare il comando seguente:
#
mirror -pprova
package=ildp site=ftp.pluto.linux.it remote_dir=/pub/pluto/ildp/ local_dir=/home/ftp/mirror/pluto/ildp/ do_deletes=true max_delete_files=50% max_delete_dirs=50% update_log=/var/log/mirror.log |
L'esempio appena mostrato è più verosimile e rappresenta la configurazione adatta a ottenere la riproduzione speculare di ILDP. In questo caso, si suppone che la directory di destinazione corretta nel proprio sistema sia /home/ftp/mirror/pluto/ildp/
.
Finora è stata descritta la riproduzione speculare di un'area FTP attraverso l'applicativo Mirror, realizzato in Perl. Per utilizzare questo programma allo scopo di ottenere la riproduzione speculare di un servizio HTTP occorre qualche trucco per aggirare l'ostacolo.
Evidentemente bisogna fare in modo che si possa accedere al servizio anche attraverso FTP (di solito come un utente normale, eventualmente con dei privilegi ridotti come accade per il tipo guest di WU-FTP). Se si vuole consentire l'accesso in qualità di utente normale, nel nodo di origine, a cui si deve poter accedere per ottenere le varie riproduzioni speculari distribuite, occorre creare un utente apposito, la cui directory personale corrisponda all'inizio della gerarchia del servizio HTTP. Dal momento che questo utente non deve fare uso di una shell, è opportuno abbinargli il programma false al suo posto, avendo cura di includere tale programma tra le shell ammissibili nel file /etc/shells
(altrimenti il servente FTP potrebbe rifiutarsi di accettare l'accesso con quel nominativo).
www:fq2243K5oN46M:33:33:Servizio HTTP:/home/httpd/html:/bin/false |
L'esempio mostra una riga ipotetica del file /etc/passwd
in cui si dichiara l'utente www necessario a permettere l'accesso all'area HTTP attraverso il protocollo FTP. Se si tenta di accedere in modo normale, non si riesce a ottenere una shell perché viene attivato al suo posto il programma false che termina subito l'esecuzione, impedendo l'accesso.
L'esempio seguente mostra la configurazione che era necessaria a definire la riproduzione speculare di Appunti di informatica libera in HTML, quando qualche tempo fa la sua origine era presso il servente linux.calion.com
. In base a questo esempio, è necessario accedere come utente www usando la parola d'ordine xxx.
package=www-al site=linux.calion.com remote_dir=/AppuntiLinux/ local_dir=/home/httpd/html/mirror/AppuntiLinux/ remote_user=www remote_password=xxx do_deletes=true max_delete_files=50% max_delete_dirs=50% update_log=/var/log/mirror.log |
Il programma Mirror, per come è stato descritto, è in grado di accedere solamente a servizi FTP conformi agli standard dei sistemi Unix. Se si deve realizzare la riproduzione speculare di un servizio FTP differente, i listati che si ottengono con il comando ls (LIST) sono diversi. In tal caso occorre leggere la documentazione originale di Mirror per trovare l'opzione giusta che permetta di accedere a tali FTP.
Come si può immaginare, per fare in modo che il sito speculare sia allineato regolarmente, si deve configurare il sistema Cron utilizzando gli orari più opportuni. L'esempio seguente mostra un pezzo del file crontab dell'utente root che avvia mirror per il pacchetto ildp alle 03:30 di ogni notte e per il pacchetto www-al alle 04:30 di ogni notte.
# mirror 30 3 * * * /usr/sbin/mirror -pildp > /dev/null 30 4 * * * /usr/sbin/mirror -pwww-al > /dev/null |
Per completezza viene mostrato come si dovrebbe trasformare l'esempio nel caso si tratti del file /etc/crontab
, in cui i comandi di Cron riportano anche l'indicazione dell'utente per conto del quale devono essere avviati.
# mirror 30 3 * * * root /usr/sbin/mirror -pildp > /dev/null 30 4 * * * root /usr/sbin/mirror -pwww-al > /dev/null |
La creazione di una riproduzione speculare di un servizio HTTP, attraverso lo stesso protocollo HTTP, è più complicato rispetto a quando è possibile usare il protocollo FTP. Infatti, i vari serventi HTTP sono predisposti in modo da nascondere quanto contenuto effettivamente nelle directory, basti pensare al fatto che convenzionalmente, quando si accede a un URI che fa capo a una directory, si ottiene quasi sempre il file index.html
.
Per poter realizzare una riproduzione speculare in queste condizioni, occorre che il programma che si utilizza sia in grado di seguire i vari riferimenti ipertestuali contenuti nelle pagine HTML, a partire da quella dell'indice.
Il primo effetto collaterale di questo meccanismo sta nel fatto che poi si pongono dei problemi quando questi riferimenti si muovono all'indietro, in directory precedenti al punto scelto come partenza, oppure, peggio, si rivolgono a nodi differenti (reali o virtuali che siano).
Quando si incontrano dei riferimenti assoluti, contenenti un URI completo dell'informazione del nodo, si aggiunge la necessità di verificare se si tratta dello stesso nodo (e quindi si possono modificare convenientemente) oppure se si tratta di un nodo differente.
Eventualmente, un programma del genere potrebbe prendersi cura di tentare di verificare la corrispondenza del nome contenuto nell'URI con quello dell'origine da cui si prelevano le informazioni, ma in tal caso, occorre tenere conto anche dei possibili alias che un nodo potrebbe avere nella rete.(3)
Il programma Wget (4) è in grado di prelevare file utilizzando sia il protocollo HTTP, sia FTP. La sua caratteristica più importante è la capacità di operare sullo sfondo, senza bisogno di un terminale attivo. In questo senso, è anche insensibile al segnale SIGHUP.(5)
Wget è predisposto normalmente per il prelievo di un file singolo; in questo senso, quando si utilizza il protocollo FTP per indicare un URI che fa riferimento a una directory, quello che si ottiene è un file HTML contenente l'indice di quella directory. La stessa cosa vale per il protocollo HTTP quando si fa riferimento a una directory per la quale il servente fornisce l'elenco del contenuto.
A seconda del fatto che si usi Wget per prelevare materiale attraverso il protocollo HTTP o FTP, il suo comportamento può essere differente; in particolare, quando si utilizza l'FTP, è possibile l'indicazione di caratteri jolly per fare riferimento a un gruppo di file.
La scansione ricorsiva deve essere richiesta in modo esplicito attraverso le opzioni o la configurazione, ma mentre nel caso dell'FTP si tratta di un processo abbastanza intuitivo attraverso cui si discendono le varie directory, quando si utilizza il protocollo HTTP significa seguire i riferimenti ipertestuali che si incontrano.
Per raggiungere gli oggetti che si vogliono scaricare si utilizzano degli URI, la cui forma può essere espressa dalle sintassi seguenti.
http://host[:porta]/[percorso]
ftp://host[:porta]/[percorso]
http://utente[:parola_d'ordine]@host[:porta]/[percorso]
ftp://utente[:parola_d'ordine]@host/[percorso]
Generalmente, con il protocollo HTTP, l'indicazione di un utente e di una parola d'ordine non è richiesta e di conseguenza si salta. Nel caso del protocollo FTP è invece obbligatoria l'identificazione: quando queste informazioni non vengono fornite, né nell'URI, né nelle opzioni e nemmeno nei file di configurazione, si utilizza il noto utente anonimo (ftp).
Come accennato, l'utente e la parola d'ordine possono essere forniti attraverso opzioni della riga di comando o direttive dei file di configurazione. A questo proposito, è importante osservare che si gestiscono due coppie diverse di nominativo-utente e parola d'ordine: una per il protocollo FTP e una per HTTP.
L'indicazione della parola d'ordine nella stessa riga di comando (nell'URI o nelle opzioni) è pericolosa perché risulta visibile nell'elenco dei processi in esecuzione. |
Wget può essere configurato attraverso due file di configurazione: /etc/wgetrc
e ~/.wgetrc
. Il primo rappresenta la configurazione dell'intero sistema e potrebbe essere collocato anche in altre posizioni del file system, a seconda della particolare distribuzione GNU che si utilizza; il secondo è il file di configurazione personalizzato. Le direttive contenute nel file di configurazione personale prendono il sopravvento su quelle della configurazione globale di sistema.
In ultima analisi, le opzioni della riga di comando prendono il sopravvento sulla configurazione.
Il contenuto di questi due file di configurazione segue le stesse regole sintattiche. I commenti sono preceduti dal simbolo # e così sono ignorate anche le righe bianche. Le direttive vengono espresse in forma di assegnamento di variabile, come indicato di seguito:
nome = valore
Per la precisione si distingue tra direttive che si riferiscono a modalità di funzionamento che possono essere attivate o disattivate, a cui si assegnano le parole chiave on oppure off, da quelle a cui deve essere assegnata una stringa contenente una qualche informazione. In particolare, in questo ultimo caso, se si indica una direttiva in cui non si assegna alcun valore, si intende azzerare implicitamente quanto definito precedentemente per quella funzione di Wget (lo stesso ragionamento vale naturalmente anche per le opzioni della riga di comando).
wget [opzioni] uri...
Wget si materializza in pratica nell'eseguibile wget. Come si può vedere dalla sintassi, l'uso di questo programma può essere molto semplice. È necessaria l'indicazione di almeno un URI e in mancanza di altri dati si intende ottenere solo la copia dell'oggetto a cui fa riferimento l'URI stesso (se si tratta di una directory di un FTP, si ottiene solo l'indice del contenuto).
La cosa più importante e delicata che può essere regolata attraverso le opzioni è la scansione ricorsiva del punto di origine, soprattutto quando l'URI di partenza fa riferimento al protocollo HTTP.
wget è esente da segnali SIGHUP e per questo è adatto particolarmente all'uso sullo sfondo (background), ma in tal caso è sempre meglio utilizzare nohup per sicurezza, perché alcune shell provvedono a eliminare i processi loro discendenti quando loro stesse terminano di funzionare.
La sintassi indicata è solo una semplificazione; in realtà, l'URI, pur essendo un'informazione necessaria, potrebbe essere fornito attraverso un file locale contenente uno o più riferimenti da scandire.
Nell'elenco seguente vengono elencate alcune opzioni elementari, assieme alle direttive corrispondenti dei file di configurazione.
Gli esempi seguenti partono dal presupposto che non sia stato predisposto alcun file di configurazione, per cui tutto quanto è descritto dalla riga di comando.
$
wget "http://dinkel.brot.dg/listino.html"
Preleva il file listino.html
dall'URI http://dinkel.brot.dg/listino.html
, salvandolo nella directory corrente.
$
wget "ftp://dinkel.brot.dg/pub/listino.html"
Preleva il file listino.html
dall'URI ftp://dinkel.brot.dg/pub/listino.html
, salvandolo nella directory corrente.
$
wget "http://dinkel.brot.dg/"
Genera il file index.html
nella directory corrente, contenente quanto restituito dall'URI http://dinkel.brot.dg/
(potrebbe trattarsi effettivamente dell'elenco del contenuto oppure di una pagina di ingresso).
$
wget "ftp://dinkel.brot.dg/"
Genera il file index.html
nella directory corrente, contenente l'elenco del contenuto dell'URI ftp://dinkel.brot.dg/
.
$
wget -r "ftp://dinkel.brot.dg/pub/progetto/"
Riproduce l'URI ftp://dinkel.brot.dg/pub/progetto/
con tutto il contenuto della directory specificata e di quelle successive fino al massimo numero di livelli predefinito (cinque), generando il percorso ./dinkel.brot.dg/pub/progetto/...
nella directory corrente.
$
wget -r -l inf "ftp://dinkel.brot.dg/pub/progetto/"
Come nell'esempio precedente, ma viene riprodotto tutto il ramo progetto/
, senza limiti di livelli di ricorsione. Infatti, trattandosi di un URI FTP, non si pongono problemi a questo tipo di scelta, dal momento che la struttura ha un termine.
$
wget -r -l inf -nc "ftp://dinkel.brot.dg/pub/progetto/"
Come nell'esempio precedente, con la differenza che, se parte dei file contenuti nell'URI remoto sono già presenti localmente, questi non vengono prelevati effettivamente.
$
nohup wget -r -l inf -nc -o ~/mio_log
<-'
`->"ftp://dinkel.brot.dg/pub/progetto/" &
Come nell'esempio precedente, con la differenza che il processo viene messo sullo sfondo (background) e viene controllato da nohup, in modo da garantire che non sia interrotto quando la shell termina di funzionare. Inoltre viene generato il file ~/mio_log
con i messaggi emessi.
$
wget -r "http://dinkel.brot.dg/progetto/"
Riproduce l'URI http://dinkel.brot.dg/progetto/
con tutto il contenuto, in base ai riferimenti che vengono incontrati, fino al massimo numero di livelli predefinito (cinque), generando il percorso ./dinkel.brot.dg/progetto/...
nella directory corrente.
$
wget -r -nc "http://dinkel.brot.dg/progetto/"
Come nell'esempio precedente, ma i file già esistenti non vengono prelevati nuovamente e di conseguenza non vengono sovrascritti.
wget permette di non indicare alcun URI nella riga di comando, utilizzando al suo posto l'inclusione di un file locale. Questa modalità viene utilizzata normalmente in modo congiunto a quella ricorsiva, ottenendo la scansione di tutti gli indirizzi URI contenuti nel file.
Il file può essere in formato HTML (è la cosa migliore) e in tal caso vengono seguiti i riferimenti ipertestuali, altrimenti può andare bene anche un file di testo contenente un elenco di indirizzi puri e semplici. Il problema si pone semmai quando il file indicato è in HTML, ma incompleto; in questo caso occorre specificare con un'opzione apposita che deve essere interpretato come HTML.
Gli indirizzi URI dovrebbero essere assoluti; se non lo sono, si può utilizzare un'opzione apposita per indicare l'URI di partenza, oppure, se si tratta di un file HTML, si può aggiungere un elemento speciale:
<base href="uri">
Tuttavia, è bene tenere presente che si tratta di un elemento non previsto nel DTD dell'HTML, quindi va usato solo in questa circostanza.
Segue la descrizione di alcuni esempi.
$
wget -r -i elenco.html
Scandisce tutti i riferimenti che trova nel file elenco.html
.
$
wget -r -i elenco --force-html
Come nell'esempio precedente, con la differenza che il file elenco
non viene riconosciuto automaticamente come HTML, per cui è stata aggiunta l'opzione --force-html.
$
wget -r -i elenco --base="http://dinkel.brot.dg/"
Viene scandito il file elenco
(il tipo di questo viene determinato in modo automatico), ma in più viene specificato che gli indirizzi relativi hanno il prefisso http://dinkel.brot.dg/
.
La scansione ricorsiva di un URI è ciò che genera i problemi maggiori nella gestione di Wget, cosa che dovrebbe essere già stata compresa dall'esposizione delle sezioni precedenti. La scansione ricorsiva di un URI di tipo FTP è abbastanza intuitiva, dal momento che si riferisce a un ramo di directory, mentre quando si tratta di un URI di tipo HTTP, questa ricorsione si basa sui riferimenti HREF e SRC; quando poi il file scaricato è di tipo text/html, questo viene scandito alla ricerca di altri riferimenti da seguire.
Soprattutto quando si opera con il protocollo HTTP, è importante porre un limite alla ricorsione, dal momento che i riferimenti possono articolarsi in modi imprevedibili. Il numero massimo predefinito di livelli di ricorsione è di cinque.
A causa delle particolarità del protocollo HTTP, può essere conveniente limitare la scansione ricorsiva ai riferimenti relativi, oppure a quelli di un dominio particolare.
Quando la scansione ricorsiva è normale, cioè non si limita ai soli riferimenti relativi, si pone il problema di trattare convenientemente i riferimenti ipertestuali assoluti che puntano allo stesso nodo in cui si trovano. Infatti, può accadere che due nomi si riferiscano allo stesso nodo; in tal caso non ha senso sdoppiare i percorsi, anche perché si rischierebbe di duplicare lo scarico di alcuni file. Per risolvere questo problema, Wget interpella il sistema DNS in modo da verificare se si tratta della stessa macchina o meno.
La vera difficoltà nasce quando il servente HTTP distingue tra nodi virtuali differenti, a cui corrisponde però lo stesso indirizzo IP, in base all'uso di un diverso alias per raggiungere lo stesso elaboratore. In tal caso, occorre informare Wget di ignorare il sistema DNS e limitarsi al confronto letterale dei nomi dei nodi.
Segue la descrizione di alcuni esempi.
$
wget -r -L -np "http://dinkel.brot.dg/progetto/"
Riproduce l'URI http://dinkel.brot.dg/progetto/
con tutto il contenuto, in base ai riferimenti relativi che vengono incontrati, escludendo quelli che si riferiscono a posizioni precedenti alla directory /progetto/
, fino al massimo numero di livelli predefinito (cinque), generando il percorso ./dinkel.brot.dg/progetto/...
nella directory corrente.
$
wget -r -L -np "http://dinkel.brot.dg/progetto/"
<-'
`->-X /progetto/img/,/progetto/x/
Come nell'esempio precedente, con l'aggiunta che non vengono riprodotte le directory /progetto/img/
e /progetto/x/
.
$
wget -r -D .brot.dg "http://dinkel.brot.dg/"
Riproduce l'URI http://dinkel.brot.dg/progetto/
seguendo anche i riferimenti ad alti nodi purché appartenenti al dominio .brot.dg
.
Quando si scandisce un URI remoto in modo ricorsivo, è possibile definire i file da scaricare in base al nome. Nel caso particolare del protocollo FTP, si possono utilizzare i noti caratteri jolly nello stesso URI, mentre con il protocollo HTTP le cose cambiano perché ci si deve sempre affidare alla scansione dei riferimenti contenuti nelle pagine HTML.
Opzione o direttiva | Descrizione |
| In questo modo si può specificare un elenco di suffissi o di modelli espressi attraverso caratteri jolly riferiti a file che si vogliono scaricare. In pratica, si scaricano solo questi file, o meglio, gli altri che sono serviti per raggiungerli vengono rimossi successivamente. |
| In questo modo si può specificare un elenco di suffissi o di modelli espressi attraverso caratteri jolly riferiti a file che non si vogliono scaricare. Tutti gli altri file vanno bene. |
Segue la descrizione di alcuni esempi.
$
wget -r -A "*.gif,*.jpg" "http://dinkel.brot.dg/progetto/"
Salva localmente solo i file che terminano per .gif
e .jpg
, provenienti dall'URI http://dinkel.brot.dg/progetto/
.
$
wget -r -R "*.gif,*.jpg" "http://dinkel.brot.dg/progetto/"
Come nell'esempio precedente, con la differenza che viene scaricato tutto fuorché i file che terminano per .gif
e .jpg
.
Si è già accennato al fatto che il nome dell'utente e la parola d'ordine eventualmente necessari per accedere a determinati servizi FTP e HTTP possono essere inseriti nello stesso URI. In alternativa si possono usare delle opzioni apposite o delle direttive dei file di configurazione.
Quando si vuole riprodurre un URI remoto e si vuole mantenere la copia locale allineata con quella remota, la cosa più importante da verificare è la variazione dell'informazione data-orario degli oggetti remoti. In pratica, si vuole ottenere che:
vengano scaricati i file remoti se non sono già presenti nel sistema locale, o se la dimensione non combacia;
vengano scaricati i file remoti se la loro data di modifica è più recente rispetto a quella dei file locali.
Opzione o direttiva | Descrizione |
| Utilizzando una di queste opzioni o direttive seguenti, si fa in modo che venga attuato il meccanismo di aggiornamento in base alla verifica delle date, evitando così di ripetere ogni volta il prelievo di dati già esistenti localmente e presumibilmente aggiornati. |
| L'opzione o la direttiva mirror incorpora in pratica la ricorsione infinita assieme a timestamping e a noclobber. |
L'esempio seguente serve a riprodurre nella directory corrente ciò che si dirama a partire da http://dinkel.brot.dg/articoli/
senza seguire riferimenti in altri nodi, né all'interno di percorsi che si articolano da posizioni precedenti gerarchicamente. In particolare vengono trasformati i riferimenti in modo che siano solo relativi (senza l'indicazione del nodo)
#
wget --mirror --relative --no-parent
<-'
`->-nH "http://dinkel.brot.dg/articoli/"
Alcune opzioni e direttive dei file di configurazione sono specifiche per l'uso con il protocollo FTP.
Altre funzionalità di Wget possono essere molto utili. Queste sezioni, tuttavia, non esauriscono la descrizione delle possibilità di Wget. Per approfondire il suo studio occorre consultare la sua documentazione, che normalmente è disponibile in forma di ipertesto Info: wget.info.
A proposito dell'opzione --spider, si fa presente che il pacchetto ImageMagick, contiene un programma che non sembra appartenere al resto. Si tratta di xtp, con il quale si può verificare la validità di un URI di tipo FTP. In alternativa, anche il programma Curl può essere usato per questo scopo, con l'opzione --list-only.
Dopo la descrizione che è stata fatta di Wget, si potrebbe analizzare la possibilità di realizzare una riproduzione speculare di URI di tipo HTTP. È già stato chiarito che quando Wget viene utilizzato per questo scopo, non si occupa di eliminare i file che dovessero essere stati rimossi dall'origine; per ottenere questo risultato occorre predisporre uno script apposito.
Per comprendere il senso della cosa si può osservare la forma del messaggio generato dall'eseguibile wget quando viene scaricato o verificato un file. Nel caso di un file che viene scaricato effettivamente si ottiene qualcosa di simile al testo seguente:
--18:19:13-- http://localhost:80/manual/index.html => `manual/index.html' Mi sto connettendo a localhost:80...connesso! HTTP richiesta inviata, aspetto la risposta... 200 OK Lunghezza: 2,158 [text/html] 0K -> .. [100%] 18:19:13 (702.47 KB/s) - `manual/index.html' salvato [2158/2158]
In alternativa, se il file esiste già e wget ritiene che sia già aggiornato:
--18:19:54-- http://localhost:80/manual/index.html => `manual/index.html' Mi sto connettendo a localhost:80...connesso! HTTP richiesta inviata, aspetto la risposta... 200 OK Lunghezza: 2,158 [text/html] Il file locale `manual/index.html' è più recente, non lo scarico.
Si può osservare in particolare la riga
=> `manual/index.html'
che contiene l'informazione del percorso corrispondente a questo file nel file system locale. Questa informazione può essere accumulata per conoscere quali sono i file aggiornati (indipendentemente dal fatto che sono stati scaricati o meno effettivamente) e confrontata con l'elenco di file che si trova effettivamente nel file system locale, permettendo l'eliminazione dei file superflui.
Di seguito viene proposto un programma in Perl che permette di realizzare una riproduzione speculare di un URI di tipo HTTP in pratica. Questo programma deve essere avviato quando la directory corrente è quella a partire dalla quale si vuole ottenere la riproduzione locale dell'URI remoto. wget viene usato con le opzioni --mirror, --no-parent e -nH, alle quali si potrebbe aggiungere eventualmente anche --relative, se la situazione lo consente.
#!/usr/bin/perl #======================================================================= # mirror-http <URI> <opzioni-supplementari> # # Mantiene una copia speculare dell'URI indicato. # In generale, l'URI deve essere una pagina HTML. #======================================================================= #----------------------------------------------------------------------- # URI di partenza. #----------------------------------------------------------------------- $punto_di_partenza = $ARGV[0]; if ($punto_di_partenza eq "") { print STDOUT ("mirror-http URI [OPZIONI_SUPPLEMENTARI]\n"); exit (1); } #----------------------------------------------------------------------- # Directory corrente. #----------------------------------------------------------------------- $pwd = `pwd`; chomp ($pwd); #----------------------------------------------------------------------- # Opzioni per wget. #----------------------------------------------------------------------- $op_normali = "--mirror --no-parent -nH"; $op_supplementari = $ARGV[1]; #----------------------------------------------------------------------- # Elenco attuale. #----------------------------------------------------------------------- @elenco_attuale = (); $i_attuale = 0; #----------------------------------------------------------------------- # Elenco preesistente. #----------------------------------------------------------------------- @elenco_preesistente = (); $i_preesistente = 0; #----------------------------------------------------------------------- # File trovato. #----------------------------------------------------------------------- $file_trovato = 0; #----------------------------------------------------------------------- # Record letto. #----------------------------------------------------------------------- $riga = ""; #----------------------------------------------------------------------- # Avvia wget e preleva l'output. #----------------------------------------------------------------------- open (WGET, "/usr/bin/wget $op_normali $op_supplementari $punto_di_partenza 2>&1 |"); #----------------------------------------------------------------------- # Legge il risultato delle operazioni di wget e ne estrae i nomi dei # file aggiornati. #----------------------------------------------------------------------- while ($riga = <WGET>) { #------------------------------------------------------------------- # Se la riga letta contiene il simbolo «=>», allora contiene # l'informazione su un file aggiornato. #------------------------------------------------------------------- if ($riga =~ m|=>|) { #--------------------------------------------------------------- # La riga contiene il percorso di un file locale che è stato # aggiornato: occorre estrarre questo nome (si trova delimitato # da «`» e «'»). #--------------------------------------------------------------- $riga =~ m|`(.*)?'|; #--------------------------------------------------------------- # Accumula nell'array. #--------------------------------------------------------------- $elenco_attuale[$#elenco_attuale+1] = $1; } #------------------------------------------------------------------- # Riemette tutte le informazioni generate da wget. #------------------------------------------------------------------- print STDOUT ("$riga"); } #----------------------------------------------------------------------- # Chiude il flusso abbinato all'esecuzione di wget. #----------------------------------------------------------------------- close (WGET); #----------------------------------------------------------------------- # Avvia find per elencare i file esistenti effettivamente dopo # l'aggiornamento con wget. #----------------------------------------------------------------------- open (FIND, "/usr/bin/find . -type f -print |"); #----------------------------------------------------------------------- # Legge il risultato di find e accumula i nomi dei file. #----------------------------------------------------------------------- while ($riga = <FIND>) { #------------------------------------------------------------------- # Se la riga letta contiene il simbolo «./» iniziale, allora # contiene l'informazione su un file esistente. #------------------------------------------------------------------- if ($riga =~ m|^\./|) { #--------------------------------------------------------------- # La riga contiene il percorso di un file locale: # occorre estrarre questo nome togliendo il prefisso «./». #--------------------------------------------------------------- $riga =~ m|^\./(.*)|; #--------------------------------------------------------------- # Accumula nell'array. #--------------------------------------------------------------- $elenco_preesistente[$#elenco_preesistente+1] = $1; } } #----------------------------------------------------------------------- # Chiude il flusso abbinato all'esecuzione di find. #----------------------------------------------------------------------- close (FIND); #----------------------------------------------------------------------- # Scandisce i due array alla ricerca di file che devono essere # cancellati. #----------------------------------------------------------------------- #----------------------------------------------------------------------- # Scandisce prima l'array contenente i file che esistono fisicamente # nel file system locale. #----------------------------------------------------------------------- for ($i_preesistente = 0 ; $i_preesistente <= $#elenco_preesistente ; $i_preesistente++) { #------------------------------------------------------------------- # Azzera la variabile booleana che serve a indicare quando un file # deve rimanere. #------------------------------------------------------------------- $file_trovato = 0; #------------------------------------------------------------------- # Per ogni elemento dell'array, scandisce l'array contenente # l'elenco dei file aggiornati. #------------------------------------------------------------------- for ($i_attuale = 0 ; $i_attuale <= $#elenco_attuale ; $i_attuale++) { #--------------------------------------------------------------- # Verifica se i nomi corrispondono. #--------------------------------------------------------------- if ($elenco_preesistente[$i_preesistente] eq $elenco_attuale[$i_attuale]) { #----------------------------------------------------------- # Il file deve rimanere e questo ciclo interno termina. #----------------------------------------------------------- $file_trovato = 1; last; } } #------------------------------------------------------------------- # Verifica se deve cancellare il file. #------------------------------------------------------------------- if (! $file_trovato) { #--------------------------------------------------------------- # Cancella il file. #--------------------------------------------------------------- unlink $elenco_preesistente[$i_preesistente]; #--------------------------------------------------------------- # Segnala l'eliminazione #--------------------------------------------------------------- print STDOUT ("eliminato: $pwd/$elenco_preesistente[$i_preesistente]\n"); } } #----------------------------------------------------------------------- # Elimina le directory vuote. #----------------------------------------------------------------------- system ("/usr/bin/find . -type d -exec rmdir \\{\\} \\; 2> /dev/null"); #====================================================================== |
Se questo programma si chiama mirror-http, supponendo di voler riprodurre l'URI http://www.brot.dg/prove/
, è necessario definire un file HTML di partenza. Di solito si tratta di index.html
e se non è così occorre trovare un file che contenga dei riferimenti che permettano lentamente di raggiungere tutti gli altri file. Seguendo l'esempio, questo programma andrebbe usato nel modo seguente:
$
mirror-http "http://www.brot.dg/prove/index.html"
Quello che si ottiene è la riproduzione della directory prove/
a partire dalla directory corrente e l'emissione attraverso lo standard output di tutti i messaggi, con l'aggiunta dell'indicazione dei file cancellati.
All'inizio del capitolo si è accennato alla netiquette. Dal momento che la gestione di un sito speculare è una cosa impegnativa, è bene ribadire i concetti più importanti.
Prima di predisporre una riproduzione speculare di un sito qualunque occorre verificare eventuali restrizioni poste dall'amministratore del sistema di origine. Di solito si tratta di fare attenzione ai messaggi che appaiono al momento della connessione FTP o di quelli che si trovano nelle varie directory sotto forma di file che «chiedono» di essere letti (readme) o simili. Di sicuro potrebbe essere cortese una richiesta formale attraverso un messaggio di posta elettronica.
Le operazioni di allineamento vanno svolte in orari in cui il servente remoto e, possibilmente, anche quello locale, sono in relativa quiete.
Periodicamente è bene verificare che le condizioni o le restrizioni poste dal sistema remoto non siano cambiate.
daniele @ swlibero.org
1) Nel passato sono esistiti tipi di connessioni in cui l'affitto si pagava a un tanto a pacchetto (di dati). Ultimamente questa forma di contratto è in via di estinzione.
2) Mirror software libero con la restrizione di diffondere le modifiche solo in forma di file di differenze
3) Infatti, per esempio, dinkel.brot.dg
potrebbe essere la stessa cosa di www.brot.dg
.
5) Alcune shell, quando concludono la loro attività, cercano di eliminare i processi loro discendenti, senza limitarsi a inviare un semplice SIGHUP. In tal caso conviene avviare wget attraverso nohup.
Dovrebbe essere possibile fare riferimento a questa pagina anche con il nome riproduzione_speculare_e_trasferimento_dati_in_modo_automati.html
[successivo] [precedente] [inizio] [fine] [indice generale] [violazione GPL] [translators] [docinfo] [indice analitico]