[successivo] [precedente] [inizio] [fine] [indice generale] [indice ridotto] [indice analitico] [home] [volume] [parte]


Capitolo 350.   Riproduzione speculare e trasferimento dati in modo automatico

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.

350.1   Chi paga

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 è 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.

350.2   Ramificazione dei siti speculari

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.

Figura 350.1. Ramificazione.

livelli di riproduzione

350.3   Sincronizzazione

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.

350.4   Mirror

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:

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à.

350.4.1   Avvio del programma

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.

mirror [opzioni] -gindirizzo:percorso
mirror [opzioni] [file_di_configurazione]

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.

Opzione Descrizione
-ppacchetto
Questa opzione permette di indicare il «pacchetto» per il quale eseguire la riproduzione speculare. Si tratta di un nome che identifica una serie di opzioni, compresa l'indicazione del nodo remoto e della directory da duplicare, contenuto nel file mirror.defaults o in un altro equivalente definito nella stessa riga di comando.
Questa opzione può essere utilizzata più volte, a indicare così diversi pacchetti. Se questa opzione non viene usata e ci si avvale comunque del file di configurazione, si ottiene l'esecuzione dell'allineamento di tutti i pacchetti.
-n
Con questa opzione si simula l'allineamento. Lo scopo è solo quello di analizzare il funzionamento e di ottenere una traccia del procedimento che verrebbe svolto.
-gindirizzo:percorso
Con questa opzione si specifica l'indirizzo di un nodo remoto e un percorso da duplicare o allineare. Utilizzando questa opzione si presume che si voglia fare a meno del file di configurazione, come già descritto.
A seconda di come viene rappresentato il percorso, Mirror presume le intenzioni dell'utente. Precisamente, se il percorso termina con una barra obliqua normale (/) si intende che si tratti di una directory e che tutto il suo contenuto debba essere duplicato, altrimenti, il percorso viene trattato come il nome di un file preciso o un modello che rappresenta file e directory diverse. È molto probabile che l'utilizzo normale di questo programma sia volto a duplicare una directory intera, comprese le sue discendenti, per cui è bene ricordare di utilizzare la barra obliqua alla fine del percorso.
-U[file_delle_registrazioni]
Attiva la registrazione dei carichi (upload). Se il nome del file non viene specificato, questo viene creato nella directory corrente (dipende da Mirror quale sia questa directory) utilizzando lo schema upload_log.giorno.mese.anno. Per evitare che tale file venga inserito all'interno della gerarchia che viene duplicata, sarebbe bene indicare sempre questo file, quando si usa l'opzione -U, facendo attenzione a specificare un percorso assoluto, che cioè parta dalla directory radice.
-knome=valore
Una serie importante di impostazioni è definita attraverso valori da assegnare a delle variabili dichiarate nel file di configurazione. Per poter inserire tali indicazioni direttamente nella riga di comando occorre utilizzare questa opzione che, dopo -k, permette di indicare un assegnamento di questo tipo.

Segue la descrizione di alcuni esempi.

350.4.2   Configurazione

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 vengono 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 viene 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.

Variabile Descrizione
package
La direttiva package apre un gruppo che rappresenta un pacchetto. Il file di configurazione dovrebbe contenere almeno il pacchetto defaults, evidenziato dalla direttiva corrispondente package=defaults. Il valore assegnato a questa variabile deve essere un nome unico (senza spazi).
site
Il nome o l'indirizzo IP del nodo del quale si fa la riproduzione speculare.
remote_dir
Rappresenta la directory FTP remota, di cui si vuole fare la riproduzione speculare.
local_dir
La directory locale a partire dalla quale inizia la riproduzione speculare dei dati in questione.
remote_user
Permette di definire il nome dell'utente da utilizzare per la connessione FTP. Se non viene definito, si intende implicitamente che si tratti di anonymous.
remote_password
Permette di definire la parola d'ordine che dovesse essere necessaria per accedere al servizio FTP remoto. Se non si specifica, viene utilizzata quella convenzionale per l'accesso anonimo: utente@nodo.
do_deletes
Permette di definire se si intende che il programma cancelli i file locali quando non ci sono più nel punto di origine. Se non viene specificato, il valore predefinito è false, che disattiva questa possibilità.
max_delete_files
Permette di indicare il numero massimo di file che possono essere cancellati, o in alternativa la percentuale se dopo il numero segue il simbolo %. In pratica, se nel nodo remoto, per quanto riguarda ciò di cui si fa la riproduzione speculare, sono stati eliminati più file di quelli specificati con questa variabile, tali file non vengono cancellati e si ottiene solo una segnalazione di errore.
Questo permette di evitare che il contenuto della riproduzione speculare venga cancellato quando l'origine viene spostata per qualche motivo, o semplicemente eliminata del tutto.
Il valore predefinito è 10%, per motivi di sicurezza.
max_delete_dirs
Permette di indicare il numero massimo di directory che possono essere eliminate automaticamente a seguito di variazioni nell'origine. Si comporta nello stesso modo della variabile max_delete_files; anche in questo caso il valore predefinito è 10%.
update_log
Questa variabile serve a definire il percorso di un file da utilizzare per annotare le operazioni svolte. Se il file esiste, le notizie vengono aggiunte a questo. Se non si indica un percorso assoluto, si intende un percorso relativo alla directory definita attraverso la variabile local_dir.
user
Permette di definire il nome o il numero UID dell'utente a cui attribuire la proprietà dei file e delle directory che vengono create. Se non viene specificato, viene usato l'utente che è proprietario del processo, ovvero colui che ha avviato Mirror. Se viene specificato qualcosa, è anche necessario che Mirror sia stato avviato con i privilegi dell'utente root, altrimenti è impossibile cambiare la proprietà dei file e delle directory.
group
Permette di definire il nome o il numero GID del gruppo a cui attribuire la proprietà dei file e delle directory che vengono create.
file_mode
Permette di definire la modalità dei permessi attribuiti ai file creati localmente. Il valore predefinito è 04448, corrispondente ai soli permessi di lettura per tutti i tipi di utenti.
dir_mode
Permette di definire la modalità dei permessi attribuiti alle directory create localmente. Il valore predefinito è 07558, corrispondente ai permessi di lettura e attraversamento per tutti, aggiungendo il permesso di scrittura per l'utente proprietario (diversamente, Mirror stesso non avrebbe modo di modificarne il contenuto).

Mirror è altamente configurabile e quanto qui riportato è solo una piccola parte delle variabili su cui si potrebbe intervenire. Per conoscere le altre caratteristiche si può consultare la pagina di manuale mirror(1)

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[Invio]

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/.

350.4.3   Riproduzione speculare di un'area HTTP

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.

È bene chiarire che la proprietà dei file contenuti nella gerarchia da cui si diramano i documenti HTML deve essere di un utente e di un gruppo diverso dall'ipotetico www, altrimenti si rischierebbe di consentire agli utenti FTP a cui si comunica la parola d'ordine di alterarne il contenuto.

L'esempio seguente mostra la configurazione 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

350.4.4   Riproduzione speculare di servizi FTP non Unix

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.

350.4.5   Attivazione automatica della procedura di allineamento

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

350.5   Riproduzione speculare attraverso il protocollo HTTP

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)

350.6   Wget

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.

Quando si utilizza Wget per replicare un'area FTP particolare, la differenza fondamentale tra questo e il programma Mirror, sta nel fatto che Wget non è predisposto per eliminare i file che nell'origine sono stati rimossi.

350.6.1   Forma dell'URI

Per raggiungere gli oggetti che si vogliono scaricare si utilizzano degli URI, la cui forma può essere espressa dalle sintassi seguenti.

http://nodo[:porta]/[percorso]
ftp://nodo[:porta]/[percorso]
http://utente[:parola_d'ordine]@nodo[:porta]/[percorso]
ftp://utente[:parola_d'ordine]@nodo/[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.

350.6.2   File di configurazione

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).

350.6.3   Utilizzo del programma

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.

Opzione o direttiva Descrizione
-o file
--output-file=file
Durante il suo funzionamento, vengono generati dei messaggi che normalmente sono emessi attraverso lo standard output. Per evitare che ciò avvenga si può utilizzare questa opzione in modo da creare il file indicato, mettendoci dentro tali messaggi. Se questo file dovesse esistere già, verrebbe cancellato.
-a file
--append-output=file
Invia nel file indicato i messaggi che altrimenti sarebbero destinati allo standard output, come con l'opzione -o, con la differenza che i dati vengono aggiunti al file, se questo esiste già.
-v
--verbose
verbose = on
Attiva la modalità dettagliata in cui tutte le informazioni vengono emesse. A meno che il programma sia stato compilato in modo particolare, si tratta sempre della modalità predefinita.
-nv
verbose = off
Questa opzione, permette di disattivare la modalità dettagliata, facendo in modo che siano generati solo i messaggi essenziali.
-r
--recursive
recursive = on
Questa opzione permette di eseguire una scansione ricorsiva.
-l n_livelli
--level=n_livelli
reclevel = n_livelli
Specifica la profondità massima di ricorsione. Questa indicazione è fondamentale quando si vuole riprodurre un URI di tipo HTTP, perché i riferimenti possono andare in ogni direzione. Il valore predefinito è di cinque livelli.
-nc
--no-clobber
noclobber = on
In condizioni normali, quando si esegue una scansione ricorsiva allo scopo di prelevare una copia di un URI remoto, i file che dovessero essere già presenti nel sistema locale, verrebbero sovrascritti. Utilizzando questa opzione, si evita la sovrascrittura, ma soprattutto si evita che questi vengano caricati dal nodo remoto. Se si tratta di file HTML, cioè file da cui si può partire per un livello di ricorsione successivo, questi vengono semplicemente letti dal sistema locale.
In tal modo, questa opzione è importante per riprendere lo scarico di un URI remoto che in precedenza è stato interrotto.
-t n_tentativi
--tries=n_tentativi
tries = n_tentativi
Permette di definire un numero di tentativi per accedere alla risorsa. Se si utilizza il numero zero, o la parola chiave inf, si intende fare in modo che wget tenti all'infinito.
-P directory_locale
--directory-prefix=directory_locale
dir_prefix = directory_locale
Permette di definire una posizione diversa dalla directory corrente per lo scarico dei file dall'URI remoto.

Gli esempi seguenti partono dal presupposto che non sia stato predisposto alcun file di configurazione, per cui tutto quanto è descritto dalla riga di comando.

350.6.4   Scansione a partire da un file locale

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.

Opzione o direttiva Descrizione
-i file
--input-file=file
input = file
Permette di indicare il file (HTML o un semplice elenco di URI) da utilizzare come punto di partenza per una scansione ricorsiva.
-F
--force-html
force_html = on
Richiede di interpretare il file indicato come HTML.
--base=uri
base = uri
Specifica esplicitamente un URI di partenza per i riferimenti relativi contenuti nel file.

Segue la descrizione di alcuni esempi.

350.6.5   Scansione ricorsiva

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.

Opzione o direttiva Descrizione
-L
--relative
relative_only = on
Fa in modo di seguire solo i riferimenti relativi, escludendo quindi qualunque URI completo dell'indicazione del nodo.
-np
--no-parent
no_parent = on
Permette di evitare che siano attraversate directory precedenti a quella dell'URI di partenza.
-X elenco_directory
--exclude elenco_directory
exclude_directories = \
  \elenco_directory
Permette di escludere un elenco di directory dalla scansione ricorsiva.
-nH
add_hostdir = off
Disabilita la creazione di directory locali prefissate dal nome del nodo di origine. Di solito, in presenza di una scansione ricorsiva di un URI, viene creata localmente una struttura di directory che riproduce il sistema remoto, a partire dal nome del nodo stesso.
Questa opzione è utile solo quando si è sicuri che i riferimenti non si sviluppano all'indietro (eventualmente attraverso l'uso di opzioni opportune), come quando si opera con URI di tipo FTP.
-nh
Disabilita il controllo DNS; in tal modo non viene verificato se due nomi di dominio appartengono in realtà allo stesso nodo.
-D elenco_domini
--domains=elenco_domini
domains = elenco_domini
Permette di definire un elenco di domini accettabili. In pratica, si permette a Wget di seguire i riferimenti a nodi differenti da quello di partenza, purché appartengano ai domini elencati.
-k
--convert-links
convert_links = on
In questo modo si ottiene di convertire i riferimenti assoluti in riferimenti relativi, limitatamente ai file scaricati effettivamente.

Segue la descrizione di alcuni esempi.

350.6.6   Selezione dei file in base al loro nome

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
-A elenco_da_accettare
--accept elenco_da_accettare
accept = elenco_da_accettare
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.
-R elenco_da_escludere
--reject elenco_da_escludere
reject = elenco_da_escludere
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.

350.6.7   Identificazioni e parole d'ordine

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.

È bene ricordare che solo inserendo le parole d'ordine all'interno del file di configurazione personale si può evitare che queste siano intercettate da altri utenti del sistema che potrebbero semplicemente leggere la riga di comando utilizzata per avviare l'eseguibile wget.

Opzione o direttiva Descrizione
--http-user utente
http_user = utente
Permette di definire il nominativo-utente da usare per una connessione HTTP a un particolare URI che richiede l'identificazione.
--http-passwd parola_d'ordine
http_passwd = parola_d'ordine
Permette di definire la parola d'ordine da usare per una connessione HTTP a un particolare URI che richiede l'identificazione.
passwd = parola_d'ordine
Permette di definire la parola d'ordine da usare per una connessione FTP.

350.6.8   Riproduzione speculare e informazioni data-orario

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:

Opzione o direttiva Descrizione
-N
--timestamping
timestamping = on
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.
-m
--mirror
mirror = on
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/"
[Invio]

Questo esempio rappresenta l'utilizzo di Wget per ottenere la riproduzione speculare di un'area HTTP. Tuttavia, il difetto di questo approccio sta nel fatto che Wget non è in grado di verificare la scomparsa di file dall'origine, per cui non può provvedere da solo alla loro eliminazione.

350.6.9   Particolarità con gli URI di tipo FTP

Alcune opzioni e direttive dei file di configurazione sono specifiche per l'uso con il protocollo FTP.

Opzione o direttiva Descrizione
-c
--continue
Permette di riprendere il prelievo di un file (uno solo) continuando da dove l'operazione è stata interrotta precedentemente. Questa opzione può essere utilizzata anche con il protocollo HTTP, se il servente relativo è predisposto per questa funzionalità.
--follow-ftp
follow_ftp = on
In questo modo si consente di seguire un riferimento a un URI di tipo FTP, quando questo è contenuto in un file HTML.
-g {on|off}
--glob={on|off}
glob = {on|off}
Permette di attivare o disattivare la possibilità di utilizzare caratteri jolly. Generalmente, questa modalità è attivata in modo predefinito.
--retr-symlinks
retr_symlinks = on
Attivando questa modalità si fa in modo che, in presenza di collegamenti simbolici, vengano scaricati i file a cui questi fanno riferimento, invece di ricreare semplicemente tali collegamenti localmente.

350.6.10   Funzionalità varie

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: info wget.

Opzione o direttiva Descrizione
-Q dimensione
--quota dimensione
quota = dimensione
Permette di definire il limite massimo di spazio utilizzabile per i prelievi, quando questi sono fatti in modo ricorsivo. Il valore della dimensione viene espresso da un numero che rappresenta una quantità di byte. Se questo numero è seguito dalla lettera k, indica unità in kibibyte (simbolo: «Kibyte»), altrimenti, se è seguito dalla lettera m, si riferisce a unità in mebibyte (simbolo: «Mibyte»).
--spider
In questo modo si ottiene soltanto la verifica che l'URI indicato rappresenti un oggetto esistente. Se l'oggetto non esiste, o non è raggiungibile, l'eseguibile wget termina di funzionare restituendo un valore diverso da zero, cosa che può servire per costruire degli script per la verifica di un elenco di URI, per esempio quello di un segnalibro di un programma di navigazione. Purtroppo, tale funzionalità non si adatta bene al protocollo FTP.
-w n_secondi
--wait n_secondi
wait = n_secondi
Permette di stabilire un intervallo di tempo tra il prelievo di un file e il successivo. È molto utile per alleggerire il carico del sistema locale, di quello remoto e dell'utilizzo della banda.

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.

350.6.11   Realizzazione di un sito speculare HTTP con Wget

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 (una copia del file dovrebbe essere disponibile anche qui: <allegati/a2/mirror-http.pl>). 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"[Invio]

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.

350.7   Netiquette

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.

  1. 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.

  2. Le operazioni di allineamento vanno svolte in orari in cui il servente remoto e, possibilmente, anche quello locale, sono in relativa quiete.

  3. Periodicamente è bene verificare che le condizioni o le restrizioni poste dal sistema remoto non siano cambiate.


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.

4) Wget   GNU GPL

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.


Appunti di informatica libera 2008 --- Copyright © 2000-2008 Daniele Giacomini -- <appunti2 (ad) gmail·com>


Dovrebbe essere possibile fare riferimento a questa pagina anche con il nome riproduzione_speculare_e_trasferimento_dati_in_modo_automati.htm

[successivo] [precedente] [inizio] [fine] [indice generale] [indice ridotto] [indice analitico] [home]

Valid ISO-HTML!

CSS validator!

Gjlg Metamotore e Web Directory