15.6. Comandi per comunicazioni

Alcuni dei comandi che seguono vengono utilizzati per la caccia agli spammer, così come per il trasferimento di dati e per l'analisi della rete.

Informazioni e statistiche

host

Cerca informazioni su un host Internet per mezzo del nome o dell'indirizzo IP usando il DNS.

bash$ host surfacemail.com
surfacemail.com. has address 202.92.42.236
	      

ipcalc

Visualizza informazioni su un indirizzo IP. Con l'opzione -h, ipcalc esegue una ricerca DNS inversa, per trovare il nome dell'host (server) a partire dall'indirizzo IP.

bash$ ipcalc -h 202.92.42.236
HOSTNAME=surfacemail.com
	      

nslookup

Esegue la "risoluzione del nome del server" di un host Internet per mezzo dell'indirizzo IP. Essenzialmente equivale a ipcalc -h o dig -x. Il comando può essere eseguito sia in modalità interattiva che non, vale a dire all'interno di uno script.

Il comando nslookup è stato immotivatamente "deprecato," ma è ancora utile.

bash$ nslookup -sil 66.97.104.180
nslookup kuhleersparnis.ch
Server:         135.116.137.2
Address:        135.116.137.2#53

Non-authoritative answer:
Name:   kuhleersparnis.ch
	      

dig

Domain Information Groper. Simile a nslookup, esegue una "risoluzione del nome del server" Internet. Può essere eseguito sia in modalità interattiva che non, cioè inserito in uno script.

Alcune interessanti opzioni di dig sono: +time=N per impostare la temporizzazione della ricerca a N secondi, +nofail per far proseguire l'interrogazione dei server finché non si sia ottenuta una risposta e -x per effettuare una risoluzione inversa.

Si confronti l'output di dig -x con ipcalc -h e nslookup.

bash$ dig -x 81.9.6.2
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 11649
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0

;; QUESTION SECTION:
;2.6.9.81.in-addr.arpa.         IN      PTR

;; AUTHORITY SECTION:
6.9.81.in-addr.arpa.    3600    IN      SOA     ns.eltel.net. noc.eltel.net.
2002031705 900 600 86400 3600

;; Query time: 537 msec
;; SERVER: 135.116.137.2#53(135.116.137.2)
;; WHEN: Wed Jun 26 08:35:24 2002
;; MSG SIZE  rcvd: 91
	      

Esempio 15-36. Scoprire dove effettuare una segnalazione di uno spammer

#!/bin/bash
# spam-lookup.sh: ricerca il contatto per segnalare uno spammer.
# Grazie a Michael Zick.

# Verifica degli argomenti da riga di comando.
CONTOARG=1
E_ERR_ARG=65
if [ $# -ne "$CONTOARG" ]
then
  echo "Utilizzo: `basename $0` nome-dominio"
  exit $E_ERR_ARG
fi


dig +short $1.contacts.abuse.net -c in -t txt
# Provate anche:
#     dig +nssearch $1
#     Cerca di trovare gli "authoritative name server" 
#+    visualizzando i record SOA. *

# Funziona anche il seguente:
#     whois -h whois.abuse.net $1
#           ^^ ^^^^^^^^^^^^^^^  Specifica l'host.  
#     In questo modo possono essere rintracciati più spammer, es."
#     whois -h whois.abuse.net $dominiospam1 $dominiospam2 . . .


#  Esercizio:
#  ---------
#  Espandete la funzionalità dello script
#+ in modo che invii automaticamente una notifica via e-mail
#+ al/gli indirizzo/i del responsabile dell'ISP.
#  Suggerimento: usate il comando "mail".

exit $?

# spam-lookup.sh chinatietong.com
#                Un noto dominio di spam.

# "crnet_mgr@chinatietong.com"
# "crnet_tec@chinatietong.com"
# "postmaster@chinatietong.com"


#  Per una versione più elaborata di questo script,
#+ vedi la pagina home di SpamViz , http://www.spamviz.net/index.html.

# * [N.d.T.]
#  Record SOA (Start of Authority). È ii record che contiene informazioni 
#+ sulla zona e indica che il server è "autoritativo" per quella zona.
 

Esempio 15-37. Analisi di un dominio di spam

#! /bin/bash
# is-spammer.sh: Identificare i domini di spam

# $Id: is-spammer, v 1.4 2004/09/01 19:37:52 mszick Exp $
# La riga precedente indica l'ID del RCS.
#
#  È la versione semplificata dello script "is_spammer.bash
#+ presente nell'appendice Script Aggiuntivi.

# is-spammer <nome.dominio>

# Viene usato il programma esterno 'dig'
# Provato con la versione 9.2.4rc5

# Uso di funzioni.
# Utilizzo di IFS per il controllo delle stringhe da assegnare agli array.
# Fa persino qualcosa di utile: controlla le blacklist dei server e-mail.

# Si usa il nome.dominio presente nell'URL:
# http://www.veramente_ottimo.spammer.biz/tutto_il_resto_ignorato
#                             ^^^^^^^^^^^
# Oppure il nome.domainio dell'indirizzo e-mail:
# Offerta_Strabiliante@spammer.biz
#
# come unico argomento dello script.
#(PS: occorre essere connessi ad internet)
#
# Concludendo, in base ai due esempi precedenti, questo script si invoca con:
#       is-spammer.sh spammer.biz


# Spaziatura == :Spazio:Tabulazione:Line Feed:A_capo:
SPZ_IFS=$'\x20'$'\x09'$'\x0A'$'\x0D'

# Nessuna spaziatura == Line Feed:A_capo
No_SPZ=$'\x0A'$'\x0D'

# Separatore di campo per gli indirizzi ip puntati
IND_IFS=${No_SPZ}'.'

# Recupera la registrazione del testo del dns.
# rec_testo <codice_errore> <server>
rec_testo() {

    # verifica $1 per l'assegnamento delle stringhe delimitate dai punti.
    local -a dns
    IFS=$IND_IFS
    dns=( $1 )
    IFS=$SPZ_IFS
    if [ "${dns[0]}" == '127' ]
    then
        # Controlla se vi è una spiegazione.
        echo $(dig +short $2 -t txt)
    fi
}

# Recupera l'indirizzo dns.
# rec_idr <dns_inv> <server>
rec_idr() {
    local risposta
    local server
    local causa

    server=${1}${2}
    risposta=$( dig +short ${server} )

    # Se la risposta contiene un codice d'errore . . .
    if [ ${#risposta} -gt 6 ]
    then
        causa=$(rec_testo ${risposta} ${server} )
        causa=${causa:-${risposta}}
    fi
    echo ${causa:-' non in blacklist.'}
}

# Si deve risalire all'indirizzo IP partendo dal nome di dominio.
echo "Recupero l'indirizzo di: "$1
ip_idr=$(dig +short $1)
risposta_dns=${ip_idr:-' nessuna risposta '}
echo ' Indirizzo: '${risposta_dns}

# Una risposta valida deve essere formata da almeno 4 cifre e 3 punti.
if [ ${#ip_idr} -gt 6 ]
then
    echo
    declare richiesta

    # Controllo per l'assegnamento delle stringhe tra i punti.
    declare -a dns
    IFS=$IND_IFS
    dns=( ${ip_idr} )
    IFS=$SPZ_IFS

    # Riordina gli ottetti nella sequenza adatta ad una interrogazione dns.
    dns_inv="${dns[3]}"'.'"${dns[2]}"'.'"${dns[1]}"'.'"${dns[0]}"'.'

# Controlla su: http://www.spamhaus.org (Tradizionale, ben mantenuto)
    echo -n 'spamhaus.org dice: '
    echo $(rec_idr ${dns_inv} 'sbl-xbl.spamhaus.org')

# Controlla su: http://ordb.org (Server aperti di istradamento e-mail)
    echo -n '   ordb.org  dice: '
    echo $(rec_idr ${dns_inv} 'relays.ordb.org')

# Controlla su: http://www.spamcop.net/ (Qui si possono segnalare gli spammer)
    echo -n ' spamcop.net dice: '
    echo $(rec_idr ${dns_inv} 'bl.spamcop.net')

# # # altre operazioni di blacklist # # #

# Controlla su: http://cbl.abuseat.org.
    echo -n ' abuseat.org dice: '
    echo $(rec_idr ${dns_inv} 'cbl.abuseat.org')

# Controlla su: http://dsbl.org/usage (Server vari di istradamento e-mail)
    echo
    echo 'Elenchi di server distibuiti'
    echo -n '       list.dsbl.org dice: '
    echo $(rec_idr ${dns_inv} 'list.dsbl.org')

    echo -n '   multihop.dsbl.org dice: '
    echo $(rec_idr ${dns_inv} 'multihop.dsbl.org')

    echo -n 'unconfirmed.dsbl.org dice: '
    echo $(rec_idr ${dns_inv} 'unconfirmed.dsbl.org')

else
    echo
    echo 'Indirizzo inutilizzabile.'
fi

exit 0

# Esercizi:
# --------

# 1) Verificate gli argomenti passati allo script, in caso d'errore
#    l'esecuzione deve terminare con un messaggio appropriato.

# 2) Controllate l'avvenuta connessione internet prima dell'avvio dello 
#    script, in caso contrario terminate con un appropriato messaggio d'errore.

# 3) Sostituite la "codifica" dei server BHL* con delle variabili generiche.

# 4) Impostate una temporizzazione per lo script usando l'opzione "+time="
     del comando 'dig'.
     
# * Black Hole Lists - Elenchi dei server di istradamento e-mail aperti che,
#+  come tali, sono utilizzati dagli spammer [N.d.T.].

Per un'ancor più elaborata versione dello script precedente, vedi Esempio A-28.

traceroute

Traccia il percorso intrapreso dai pacchetti inviati ad un host remoto. Questo comando funziona su una LAN, una WAN o su Internet. L'host remoto deve essere specificato per mezzo di un indirizzo IP. L'output può essere filtrato da grep o sed in una pipe.

bash$ traceroute 81.9.6.2
traceroute to 81.9.6.2 (81.9.6.2), 30 hops max, 38 byte packets
1  tc43.xjbnnbrb.com (136.30.178.8)  191.303 ms  179.400 ms  179.767 ms
2  or0.xjbnnbrb.com (136.30.178.1)  179.536 ms  179.534 ms  169.685 ms
3  192.168.11.101 (192.168.11.101)  189.471 ms  189.556 ms *
...
	      

ping

Trasmette un pacchetto "ICMP ECHO_REQUEST" ad un'altra macchina, sia su rete locale che remota. È uno strumento diagnostico per verificare le connessioni di rete e dovrebbe essere usato con cautela.

bash$ ping localhost
PING localhost.localdomain (127.0.0.1) from 127.0.0.1 : 56(84) bytes of data.
64 bytes from localhost.localdomain (127.0.0.1): icmp_seq=0 ttl=255 time=709 usec
64 bytes from localhost.localdomain (127.0.0.1): icmp_seq=1 ttl=255 time=286 usec

--- localhost.localdomain ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max/mdev = 0.286/0.497/0.709/0.212 ms
	      

Un ping che ha avuto successo restituisce exit status 0. Questo può essere verificato in uno script.

  NOMEH=nastyspammer.com
# NOMEH=$HOST     # Debugging: verifica per localhost.
conto=2  # Invia solo due ping.
		      
 if [[ `ping -c $conto "$NOMEH"` ]]
then
  echo ""$NOMEH" è ancora connesso e ti sta inviando spam."
else
   echo ""$NOMEH" sembra scollegato. Peccato."
fi

whois

Esegue una ricerca DNS (Domain Name System). L'opzione -h consente di specificare quale particolare server whois dev'essere interrogato. Vedi Esempio 4-6 e Esempio 15-36.

finger

Rintraccia informazioni sugli utenti di una rete. Opzionalmente, il comando può visualizzare i file ~/.plan, ~/.project e ~/.forward di un utente, se presenti.

bash$ finger
Login  Name           Tty       Idle  Login Time   Office     Office Phone
bozo   Bozo Bozeman   tty1        8  Jun 25 16:59
bozo   Bozo Bozeman   ttyp0          Jun 25 16:59
bozo   Bozo Bozeman   ttyp1          Jun 25 17:07



bash$ finger bozo
Login: bozo                              Name: Bozo Bozeman
 Directory: /home/bozo                   Shell: /bin/bash
 Office: 2355 Clown St., 543-1234
 On since Fri Aug 31 20:13 (MST) on tty1    1 hour 38 minutes idle
 On since Fri Aug 31 20:13 (MST) on pts/0   12 seconds idle
 On since Fri Aug 31 20:13 (MST) on pts/1
 On since Fri Aug 31 20:31 (MST) on pts/2   1 hour 16 minutes idle
 No mail.
 No Plan.
	      

Tralasciando considerazioni sulla sicurezza, molte reti disabilitano finger ed il demone ad esso associato. [1]

chfn

Modifica le informazioni rivelate dal comando finger.

vrfy

Verifica un indirizzo e-mail Internet.

Questo comando non è presente nelle più recenti distribuzioni Linux.

Accesso ad host remoto

sx, rx

La serie di comandi sx e rx serve a trasferire file a e da un host remoto utilizzando il protocollo xmodem. Generalmente fanno parte di un pacchetto comunicazioni, come minicom.

sz, rz

La serie di comandi sz e rz serve a trasferire file a e da un host remoto utilizzando il protocollo zmodem. Zmodem possiede alcuni vantaggi rispetto a xmodem, come una maggiore velocità di trasmissione e di ripresa di trasferimenti interrotti. Come sx e rx, generalmente sono compresi in un pacchetto comunicazioni.

ftp

Utility e protocollo per caricare/scaricare file su o da un host remoto. Una sessione ftp può essere automatizzata in uno script (vedi Esempio 18-6, Esempio A-4 ed Esempio A-13).

uucp, uux, cu

uucp: UNIX to UNIX copy - copia da UNIX a UNIX. È un pacchetto per comunicazioni che permette il trasferimento di file tra server UNIX. Uno script di shell rappresenta un modo efficace per gestire una sequenza di comandi uucp.

Con l'avvento di Internet e della e-mail, uucp sembra essere precipitato nel dimenticatoio, ma esiste ancora e rimane perfettamente funzionante nelle situazioni in cui una connessione Internet non è adatta o non è disponibile.

---

uux: UNIX to UNIX execute - esecuzione da UNIX a UNIX. Esegue un comando su un sistema remoto. Fa parte del pacchetto uucp.

---

cu: chiama (Call Up) un sistema remoto e si connette come semplice terminale. È una specie di versione inferiore di telnet. Anche questo comando fa parte del pacchetto uucp.

telnet

Utility e protocollo di connessione ad host remoto.

Attenzione

Nel protocollo telnet sono presenti falle inerenti alla sicurezza e, quindi, dovrebbe essere evitato.

wget

L'utility wget rintraccia o scarica in modo non-interattivo file dal Web o da un sito ftp. Funziona bene in uno script.

wget -p http://www.xyz23.com/file01.html
#  L'opzione -p o --page-requisite consente a wget di rintracciare tutti i file
#+ necessari per visualizzare la pagina specificata.

wget -r ftp://ftp.xyz24.net/~bozo/project_files/ -O $SAVEFILE
#  Segue l'opzione di ricorsività -r che recupera tutti i link
#+ presenti sul sito specificato.

Esempio 15-38. Ottenere una quotazione di borsa

#!/bin/bash
# quote-fetch.sh: Scarica una quotazione di borsa.


E_NOPARAM=66

if [ -z "$1" ]  # Si deve specificare il titolo (sigla) da cercare.
  then echo "Utilizzo: `basename $0` codice_titolo"
  exit $E_NOPARAM
fi

codice_titolo=$1

suffisso_file=.html
# Cerca un file HTML, per cui bisogna usare un nome appropriato.
URL='http://finance.yahoo.com/q?s='
# Servizio finanziario di Yahoo, con suffisso di ricerca del titolo.

# --------------------------------------------------------------
wget -O ${codice_titolo}${suffisso_file} "${URL}${codice_titolo}"
# --------------------------------------------------------------


# Per vedere la cosa all'opera su http://search.yahoo.com:
# -----------------------------------------------------------
# URL="http://search.yahoo.com/search?fr=ush-news&p=${query}"
# wget -O "$salvanomefile" "${URL}"
# -----------------------------------------------------------
# Registra un elenco di importanti URL.

exit $?

# Esercizi:
# --------
#
# 1) Aggiungete una verifica che confermi all'utente che esegue lo script
#    l'avvenuto collegamento.
#    (Suggerimento: confrontate l'output di 'ps -ax' con "ppp" o "connect."
#
# 2) Modificate lo script per scaricare il bollettino metereologico locale,
#+   fornendo come argomento il codice di avviamento postale.

Vedi anche Esempio A-30 e Esempio A-31.

lynx

Il brower per il Web ed i file lynx può essere utilizzato all'interno di uno script (con l'opzione -dump) per recuperare un file dal Web o da un sito ftp in modalità non-interattiva.

lynx -dump http://www.xyz23.com/file01.html >$SAVEFILE

Con l'opzione -traversal, lynx inizia dall'URL HTTP specificata come argomento e "scorre lentamente" tutti i link presenti su quel particolare server. Usato insieme all'opzione -crawl produce una pagine di testo inserita in un file di log.

rlogin

Remote login, inizia una sessione su un host remoto. Dal momento che questo comando ha dei problemi inerenti alla sicurezza, al suo posto è meglio usare ssh.

rsh

Remote shell, esegue comandi su un host remoto. Anch'esso ha problemi di sicurezza. Si utilizzi, quindi, ssh.

rcp

Remote copy (copia da remoto), copia file tra due differenti macchine collegate in rete.

rsync

Remote synchronize (sincronizzazione da remoto), aggiorna (sincronizza) file tra due differenti macchine collegate in rete.

bash$ rsync -a ~/dirsorgente/*txt /node1/sottodirectory/
	      

Esempio 15-39. Aggiornare FC4

#!/bin/bash
# fc4upd.sh

# Autore dello script: Frank Wang.
# Con piccole modifiche di stile effettuate dall'autore de Guida ASB.
# Utilizzato in Guida ASB con il permesso dell'autore dello script.


#  Scarica l'aggiornamento di Fedora 4 da un mirror usando rsync. 
#  Dovrebbe funzionare anche per le nuove Fedora Core -- 5, 6, . . .
#  Per risparmiare spazio, scarica solamente l'ultima versione di un pacchetto,
#+ nel caso ve ne sia più d'una.

URL=rsync://distro.ibiblio.org/fedora-linux-core/updates/
# URL=rsync://ftp.kddilabs.jp/fedora/core/updates/
# URL=rsync://rsync.planetmirror.com/fedora-linux-core/updates/

DEST=${1:-/var/www/html/fedora/updates/}
LOG=/tmp/repo-update-$(/bin/date +%Y-%m-%d).txt
PID_FILE=/var/run/${0##*/}.pid

E_RETURN=65        # Nel caso succeda qualcosa di inatteso.


# Opzioni generali di rsync
# -r: download ricorsivo
# -t: tempo rimanente
# -v: verbose - dettaglio

OPZ="-rtv --delete-excluded --delete-after --partial"

# modello di inclusione per rsync
# La barra iniziale indica la verifica del percorso assoluto.
INCLUDE=(
    "/4/i386/kde-i18n-Chinese*" 
#   ^                         ^
# È necessario il quoting per evitare il globbing.
) 


# modello di escusione per rsync
# Commentate temporaneamente i pacchetti da non considerare usando "#" . . .
ESCLUDE=(
    /1
    /2
    /3
    /testing
    /4/SRPMS
    /4/ppc
    /4/x86_64
    /4/i386/debug
   "/4/i386/kde-i18n-*"
   "/4/i386/openoffice.org-langpack-*"
   "/4/i386/*i586.rpm"
   "/4/i386/GFS-*"
   "/4/i386/cman-*"
   "/4/i386/dlm-*"
   "/4/i386/gnbd-*"
   "/4/i386/kernel-smp*"
#  "/4/i386/kernel-xen*" 
#  "/4/i386/xen-*" 
)


init () {
    #  Consente alla pipe dei comandi di visualizzare eventuali errori 
    #+ di rsync, es. stalled network.
    set -o pipefail                     #  Introdotto recentemente in 
                                        #+ Bash versione 3.

    TMP=${TMPDIR:-/tmp}/${0##*/}.$$     #  Registra la lista aggiornata 
                                        #+ del download.
    trap "{
        rm -f $TMP 2>/dev/null
    }" EXIT                             #  Cancella il file temporaneo 
                                        #+ all'uscita.
}


controlla_pid () {
# Verifica l'esistenza del processo.
    if [ -s "$PID_FILE" ]; then
        echo "Il file PID esiste?. Verifica ..."
        PID=$(/bin/egrep -o "^[[:digit:]]+" $PID_FILE)
        if /bin/ps --pid $PID &>/dev/null; then
            echo "Trovato processo $PID. ${0##*/} in esecuzione!"
           /usr/bin/logger -t ${0##*/} \
                 "Trovato processo $PID. ${0##*/} in esecuzione!"
            exit $E_RETURN
        fi
        echo "Processo $PID non trovato. Inizio un nuovo processo . . ."
    fi
}


#  Imposta l'intervallo dell'aggiornamento completo iniziando da root o da $URL,
#+ secondo quanto specificato nei modelli precedenti.
imposta_intervallo () {
    include=
    esclude=
    for p in "${INCLUDE[@]}"; do
        include="$include --include \"$p\""
    done

    for p in "${ESCLUDE[@]}"; do
        esclude="$esclude --exclude \"$p\""
    done
}


# Recupera e perfeziona l'elenco di aggiornamento rsync.
crea_lista () {
    echo $$ > $PID_FILE || {
        echo "Non posso scrivere nel file $PID_FILE"
        exit $E_RETURN
    }

    echo -n "Recupero e perfezionamento della lista di aggiornamento . . ."

    #  Recupera la lista -- 'eval' è necessario per far eseguire rsync 
    #+ come comando unico.
    #  $3 e $4 sono la data e l'ora di creazione del file.
    #  $5 è il nome completo del pacchetto.
    precedente=
    pre_file=
    pre_data=0
    eval /bin/nice /usr/bin/rsync \
        -r $include $esclude $URL | \
        egrep '^dr.x|^-r' | \
        awk '{print $3, $4, $5}' | \
        sort -k3 | \
        { while read riga; do
            #  Calcola i secondi a partire da epoch per scartare i 
            #+ pacchetti obsoleti.
            cor_data=$(date -d "$(echo $riga | awk '{print $1, $2}')" +%s)
            #  echo $cor_data

            #  Recupera il nome del file.
            cor_file=$(echo $riga | awk '{print $3}')
            #  echo $cor_file

            #  Recupera il nome del pacchetto rpm dal nome del file, 
            #+ se possibile.
            if [[ $cor_file == *rpm ]]; then
                nome_pkg=$(echo $cor_file | sed -r -e \
                    's/(^([^_-]+[_-])+)[[:digit:]]+\..*[_-].*$/\1/')
            else
                nome_pkg=
            fi
            # echo $nome_pkg

            if [ -z "$nome_pkg" ]; then   #  Se non è un file rpm,
                echo $cor_file >> $TMP    #+ lo accoda alla lista di download.
            elif [ "$nome_pkg" != "$precedente" ]; then  #  Trovato un nuovo 
                                                         #+ pacchetto.
                echo $pre_file >> $TMP                   #  Accoda il
                                                         #+ precedente.
                precedente=$nome_pkg                     #  Salva quello 
                                                         #+ corrente.
                pre_data=$cor_data
                pre_file=$cor_file
            elif [ "$cor_data" -gt "$pre_data" ]; then   #  Stesso pacchetto,
                                                         #+ ma più recente,
                pre_data=$cor_data                       #+ aggiorna il 
                                                         #+ puntatore precedente.
                pre_file=$cor_file
            fi
            done
            echo $pre_file >> $TMP                       #  TMP ora contiene la
                                                         #+ lista COMPLETA e 
                                                         #+ aggiornata.
            # echo "subshell=$BASH_SUBSHELL"

    }       #  Le parentesi graffe sono necessarie per consentire a 
            #+ "echo $pre_file >> $TMP" finale di rimanere nella stessa
            #+ subshell ( 1 ) assiema all'intero ciclo.
	    
    RIT=$?  # Recupera il codice di ritorno della pipe.

    [ "$RIT" -ne 0 ] && {
        echo "Recupero della lista fallito con codice $RET"
        exit $E_RETURN
    }

    echo "fatto"; echo
}

# Download di rsync.
scarica_file () {

    echo "In download..."
    /bin/nice /usr/bin/rsync \
        $OPZ \
        --filter "merge,+/ $TMP" \
        --exclude '*'  \
        $URL $DEST     \
        | /usr/bin/tee $LOG

    RIT=$?

        #  --filter merge,+/ è cruciale allo scopo. 
        #  + il modificatore significa includi e / percorso assoluto.
        #  Quindi, l'elenco ordinato presente in $TMP conterrà i nomi delle
        #+ directory in ordine ascendente impedendo al successivo 
        #+ --exclude '*' di mandare tutto in "corto circuito." 

    echo "Fatto"

    rm -f $PID_FILE 2>/dev/null

    return $RIT
}

# -------
# Main
init
controlla_pid
imposta_intervallo
crea_lista
scarica_file
RIT=$?
# -------

if [ "$RIT" -eq 0 ]; then
    /usr/bin/logger -t ${0##*/} "Fedora aggiornata con successo."
else
    /usr/bin/logger -t ${0##*/} "Aggiornamento di Fedora fallito con codice: $RIT"
fi

exit $RIT

Vedi anche Esempio A-32.

Nota

L'uso di rcp, rsync ed utility simili, che hanno problemi di sicurezza, in uno script di shell potrebbe non essere consigliabile. Si consideri, invece, l'utilizzo di ssh, scp o di uno script expect.

ssh

Secure shell, si connette ad un host remoto e vi esegue dei comandi. Questo sostituto di sicurezza di telnet, rlogin, rcp e rsh utilizza l'autenticazione e la cifratura. Per i dettagli, si veda la sua pagina di manuale.

Esempio 15-40. Uso di ssh

#!/bin/bash
# remote.bash: Uso di ssh.

# Esempio di Michael Zick.
# Usato con il consenso dell'autore.


#   Presupposti:
#   -----------
#   il df-2 non dev'esere stato impegnato ( '2>/dev/null' ).
#   ssh/sshd presumono che lo stderr ('2') verrà visualizzato all'utente.
#
#   sshd deve essere in esecuzione sulla macchina.
#   Probabilmente questa è la situazione per qualsiasi distribuzione 'standard',
#+  e senza aver fatto qualche strana impostazione di ssh-keygen.

# Provate ssh da riga di comando sulla vostra macchina:
#
# $ ssh $HOSTNAME
# Se non sono state fatte impostazioni ulteriori, vi verrà chiesta la password.
#   inserite la password
#   quindi  $ exit
#
# Ha funzionato? In questo caso siete pronti per un altro po' di divertimento.

# Provate ssh come utente 'root':
#
#   $  ssh -l root $HOSTNAME
#   Quando vi verrà chiesta la password, inserite quella di root, non la vostra.
#          Last login: Tue Aug 10 20:25:49 2004 from localhost.localdomain
#   Dopo di che 'exit'.

#  I comandi precedenti forniscono una shell interattiva.
#  È possibile impostare sshd in modalità 'comando singolo',
#+ ma questo va oltre lo scopo dell'esempio.
#  L'unica cosa da notare è che quello che segue funziona
#+ in modalità 'comando singolo'.


# Il fondamentale comando di visualizzazione allo stdout (locale).

ls -l

# E ora lo stesso comando su una macchina remota.
# Se desiderate, potete passare 'USERNAME' 'HOSTNAME' diversi:
USER=${USERNAME:-$(whoami)}
HOST=${HOSTNAME:-$(hostname)}

#  Ora eseguiamo la precedente riga di comando su un host remoto,
#+ la trasmissione è totalmente criptata.

ssh -l ${USER} ${HOST} " ls -l "

#  Il risultato atteso è l'elenco dei file della directory home dell'utente
#+ presente sulla macchina remota.
#  Se volete vedere delle differenze, eseguite lo script da una qualsiasi directory
#+ diversa dalla vostra directory home.

#  In altre parole, il comando Bash viene passato come stringa tra apici
#+ alla shell remota, che lo esegue sulla macchina remota.
#  In questo caso sshd esegue  ' bash -c "ls -l" '   per conto vostro.

#  Per informazioni su argomenti quali il non dover inserire la
#+ password/passphrase ad ogni riga di comando, vedi
#+    man ssh
#+    man ssh-keygen
#+    man sshd_config.

exit 0

Attenzione

In un ciclo, ssh potrebbe causare un comportamento inatteso. Secondo un post Usenet negli archivi shell di comp.unix, ssh eredita lo stdin del ciclo. Per porvi rimedio, si passi ad ssh o l'opzione -n o l'opzione -f.

Grazie a Jason Bechtel per la precisazione.

scp

Secure copy, ha la stessa funzionalità di rcp, copia, cioè, file tra due differenti macchine collegate in rete. Ma lo fa utilizzando l'autenticazione e con un livello di sicurezza simile a ssh.

Rete Locale

write

È l'utility per la comunicazione terminale-terminale. Consente di inviare righe di testo dal vostro terminale (console o xterm) a quello di un altro utente. Si può usare, naturalmente, il comando mesg per disabilitare l'accesso di write in scrittura su di un terminale.

Poiché write è interattivo, normalmente non viene impiegato in uno script.

netconfig

Utility da riga di comando per la configurazione di un adattatore di rete (utilizzo di DHCP). È un comando nativo delle distribuzioni Linux somiglianti a Red Hat.

Posta

mail

Invia o legge messaggi e-mail.

Questo client da riga di comando per il recupero della posta funziona altrettanto bene come comando inserito in uno script.

Esempio 15-41. Uno script che si auto-invia

#!/bin/sh
# self-mailer.sh: Script che si auto-invia

adr=${1:-`whoami`}    # Imposta l'utente corrente come predefinito, se
                      #+ non altrimenti specificato.
#  Digitando 'self-mailer.sh wiseguy@superdupergenius.com'
#+ questo script viene inviato a quel destinatario.
#  Il solo 'self-mailer.sh' (senza argomento) invia lo script alla
#+ persona che l'ha invocato, per esempio, bozo@localhost.localdomain
#
#  Per i dettagli sul costrutto  ${parametro:-default}, vedi la sezione 
#+ "Sostituzione di Parametro" del capitolo "Variabili Riviste".

# =========================================================================
  cat $0 | mail -s " Lo script \"`basename $0`\" si è auto-inviato." "$adr"
# =========================================================================

# --------------------------------------------------
#  Saluti dallo script che si auto-invia.
#  Una persona maliziosa ha eseguito questo script,  
#+ che ne ha provocato l'invio a te. Apparentemente, 
#+ certa gente non ha niente di meglio da fare 
#+ con il proprio tempo.
# --------------------------------------------------

echo "Il `date`, lo script \"`basename $0`\" è stato inviato a "$adr"."

exit 0
mailto

Simile al comando mail, mailto invia i messaggi e-mail da riga di comando o da uno script. Tuttavia, mailto consente anche l'invio di messaggi MIME (multimedia).

vacation

Questa utility risponde in automatico alle e-mail indirizzate ad un destinatario che si trova in vacanza o temporaneamente indisponibile. Funziona su una rete, in abbinamento con sendmail, e non è utilizzabile per un account di posta POP in dial-up.

Note

[1]

Un demone è un processo in esecuzione in background non collegato ad una sessione di terminale. I demoni eseguono servizi specifici sia ad ore indicate che al verificarsi di particolari eventi.

La parola "demone" in greco significa fantasma, e vi è certamente qualcosa di misterioso quasi soprannaturale, nel modo in cui i demoni UNIX vagano dietro le quinte eseguendo silenziosamente i compiti a loro assegnati.