cat e' l'acronimo di concatenato, visualizza un file allo stdout. In combinazione con gli operatori di redirezione (> o >>) e' comunemente usato per concatenare file. 1 # Usi di 'cat' 2 cat nomefile # Visualizza il contenudo del file. 3 4 cat file.1 file.2 file.3 > file.123 # Concatena tre file in uno. L'opzione -n di cat numera consecutivamente le righe del/dei file di riferimento. L'opzione -b numera solo le righe non vuote. L'opzione -v visualizza i caratteri non stampabili, usando la notazione ^ . L'opzione -s comprime tutte le righe vuote consecutive in un'unica riga vuota. Vedi anche Esempio 12-25 e Esempio 12-21. Nota In una pipe, risulta piu' efficiente redirigere lo stdin in un file piuttosto che usare cat. 1 cat nomefile | tr a-z A-Z 2 3 tr a-z A-Z < nomefile # Stesso risultato, ma si avvia un processo in meno, 4 #+ e senza dover usare la pipe. tac e' l'inverso di cat e visualizza un file in senso contrario, vale a dire, partendo dalla fine. rev inverte ogni riga di un file e la visualizza allo stdout. Non ha lo stesso effetto di tac poiché viene preservato l'ordine delle righe, semplicemente rovescia ciascuna riga. bash$ cat file1.txt Questa e' la riga 1. Questa e' la riga 2. bash$ tac file1.txt Questa e' la riga 2. Questa e' la riga 1. bash$ rev file1.txt .1 agir al e' atseuQ .2 agir al e' atseuQ cp e' il comando per la copia dei file. cp file1 file2 copia file1 in file2, sovrascrivendo file2 nel caso esistesse gia' (vedi Esempio 12-6). Suggerimento Sono particolarmente utili le opzioni -a di archiviazione (per copiare un intero albero di directory), -u di aggiornamento, e -r e -R di ricorsivita'. 1 cp -u dir_sotgente/* dir_destinazione 2 # "Sincronizza" dir_destinazione con dir_sorgente 3 #+ copiando i file piu' recenti e quelli precedentemente inesistenti. mv e' il comando per lo spostamento di file. e' equivalente alla combinazione di cp e rm. Puo' essere usato per spostare piu' file in una directory o anche per rinominare una directory. Per alcune dimostrazioni sull'uso di mv in uno script, vedi Esempio 9-18 e Esempio A-2. Nota Se usato in uno script non interattivo, mv vuole l'opzione -f (forza) per evitare l'input dell'utente. Quando una directory viene spostata in un'altra preesistente, diventa la sottodirectory di quest'ultima. bash$ mv directory_iniziale directory_destinazione bash$ ls -lF directory_destinazione total 1 drwxrwxr-x 2 bozo bozo 1024 May 28 19:20 directory_iniziale/ rm Cancella (rimuove) uno o piu' file. L'opzione -f forza la cancellazione anche dei file in sola lettura. e' utile per evitare l'input dell'utente in uno script. Nota Il semplice comando rm non riesce a cancellare i file i cui nomi iniziano con un trattino. bash$ rm -bruttonome rm: invalid option -- b Try `rm --help' for more information. Un modo per riuscirci e' far precedere il nome del file che deve essere rimosso da punto-barra. bash$ rm ./-bruttonome Un metodo alternativo e' far predere il nome del file da " -- ". bash$ rm -- -bruttonome Attenzione Se usato con l'opzione di ricorsivita' -r, il comando cancella tutti i file della directory corrente. Uno sbadato rm -rf * puo' eliminare buona parte della struttura di una directory. rmdir Cancella una directory. Affinché questo comando funzioni e' necessario che la directory non contenga alcun file -- neanche gli "invisibili" dotfile [1]. mkdir Crea una nuova directory. Per esempio, mkdir -p progetto/programmi/Dicembre crea la directory indicata. L'opzione -p crea automaticamente tutte le necessarie directory indicate nel percorso. chmod Modifica gli attributi di un file esistente (vedi Esempio 11-12). 1 chmod +x nomefile 2 # Rende eseguibile "nomefile" per tutti gli utenti. 3 4 chmod u+s nomefile 5 # Imposta il bit "suid" di "nomefile". 6 # Un utente comune puo' eseguire "nomefile" con gli stessi privilegi del 7 #+ proprietario del file (Non e' applicabile agli script di shell). 1 chmod 644 nomefile 2 # Da' al proprietario i permessi di lettura/scrittura su "nomefile", il 3 #+ permesso di sola lettura a tutti gli altri utenti 4 # (modalita' ottale). 1 chmod 1777 nome-directory 2 # Da' a tutti i permessi di lettura, scrittura ed esecuzione nella 3 #+ directory, inoltre imposta lo "sticky bit". Questo significa che solo il 4 #+ proprietario della directory, il proprietario del file e, naturalmente, root 5 #+ possono cancellare dei file particolari presenti in quella directory. chattr Modifica gli attributi del file. Ha lo stesso effetto di chmod, visto sopra, ma con sintassi ed opzioni diverse, e funziona solo su un filesystem di tipo ext2. Un'opzione particolarmente interessante di chattr e' i. chattr +i nomefile contrassegna quel file come immodificabile. Il file non puo' essere in alcun modo modificato, soggetto a link o cancellato, neanche da root. Questo attributo puo' essere impostato o rimosso solo da root. In modo simile, l'opzione a contrassegna il file come scrivibile, ma solo per accodamento. root# chattr +i file1.txt root# rm file1.txt rm: remove write-protected regular file `file1.txt'? y rm: cannot remove `file1.txt': Operation not permitted Se un file ha impostato l'attributo s (secure), in caso di cancellazione il/i blocco/hi che occupava sul disco verra'/anno sovrascritto/i con degli zero. Se un file ha impostato l'attributo u (undelete), in caso di cancellazione sara' ancora possibile recuperarne il contenuto (non cancellato). Se un file ha impostato l'attributo c (compress), viene automaticamente compresso prima della scrittura su disco e decompresso per la lettura. Nota Gli attributi di un file impostati con chattr non vengono elencati (se si e' usato (ls -l). ln Crea dei link a file esistenti. Un "link" e' un riferimento a un file, un nome alternativo. Il comando ln permette di fare riferimento al file collegato (linkato) con piu' di un nome e rappresenta un'alternativa di livello superiore all'uso degli alias (vedi Esempio 4-6). ln crea semplicemente un riferimento, un puntatore al file, che occupa solo pochi byte. Il comando ln e' usato molto spesso con l'opzione -s, simbolico o "soft". Uno dei vantaggi dell'uso dell'opzione -s e' che consente link alle directory o a file di filesystem diversi. La sintassi del comando e' un po' ingannevole. Per esempio: ln -s vecchiofile nuovofile collega nuovofile, creato con l'istruzione, all'esistente vecchiofile. Cautela Nel caso sia gia' presente un file di nome nuovofile, viene visualizzato un messaggio d'errore. Quale tipo di link usare? Ecco la spiegazione di John Macdonald: Entrambi i tipi (simbolico e hard [N.d.T.]) forniscono uno strumento sicuro di referenziazione doppia -- se si modifica il contenuto del file usando uno dei due nomi, le modifiche riguarderanno sia il file con il nome originario che quello con il nome nuovo, sia esso un hard link oppure un link simbolico. Le loro differenze si evidenziano quando si opera ad un livello superiore. Il vamtaggio di un hard link e' che il nuovo nome e' completamente indipendente da quello vecchio -- se si cancella o rinomina il vecchio file, questo non avra' alcun effetto su un hard link, che continua a puntare ai dati reali, mentre spezzerebbe un link simbolico che punta al vecchio nome che non esiste piu'. Il vantaggio di un link simbolico e' che puo' far riferimento ad un diverso filesystem (dal momento che si tratta di un semplice collegamento al nome di un file, non ai dati reali). E, a differenza di un hard link, puo' far riferimento a una directory. Con i link si ha la possibilita' di invocare uno stesso script (o qualsiasi altro eseguibile) con nomi differenti ottenendo un comportamento diverso in base al nome con cui e' stato invocato. Esempio 12-2. Ciao o arrivederci 1 #!/bin/bash 2 # hello.sh: Visualizzare "ciao" o "arrivederci" 3 #+ secondo le modalita' di invocazione dello script. 4 5 # Eseguiamo un collegamento allo script nella directory di lavoro corrente($PWD): 6 # ln -s hello.sh goodbye 7 # Ora proviamo ad invocare lo script in entrambi i modi: 8 # ./hello.sh 9 # ./goodbye 10 11 12 CHIAMATA_CIAO=65 13 CHIAMATA_ARRIVEDERCI=66 14 15 if [ $0 = "./goodbye" ] 16 then 17 echo "Arrivederci!" 18 # Se si desidera, qualche altro saluto dello stesso tipo. 19 exit $CHIAMATA_ARRIVEDERCI 20 fi 21 22 echo "Ciao!" 23 # Qualche altro comando appropriato. 24 exit $CHIAMATA_CIAO VARIE 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 puo' essere eseguito sia in modalita' interattiva che non, vale a dire all'interno di uno script. Il comando nslookup e' stato immotivatamente "deprecato," ma viene ancora utilizzato. 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. Puo' essere eseguito sia in modalita' interattiva che non, vale a dire 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 12-36. Scoprire dove effetuare una segnalazione di uno spammer 1 #!/bin/bash 2 # spam-lookup.sh: ricerca il contatto per segnalare uno spammer. 3 # Grazie a Michael Zick. 4 5 # Verifica degli argomenti da riga di comando. 6 CONTOARG=1 7 E_ERR_ARG=65 8 if [ $# -ne "$CONTOARG" ] 9 then 10 echo "Utilizzo: `basename $0` nome-dominio" 11 exit $E_ERR_ARG 12 fi 13 14 15 dig +short $1.contacts.abuse.net -c in -t txt 16 # Provate anche: 17 # dig +nssearch $1 18 # Cerca di trovare gli "authoritative name server" 19 #+ visualizzando i record SOA. * 20 21 # Funziona anche il seguente: 22 # whois -h whois.abuse.net $1 23 # ^^ ^^^^^^^^^^^^^^^ Specifica l'host. 24 # In questo modo possono essere rintracciati piu' spammer, es." 25 # whois -h whois.abuse.net $dominiospam1 $dominiospam2 . . . 26 27 28 # Esercizio: 29 # --------- 30 # Espandete la funzionalita' dello script 31 #+ in modo che invii automaticamente una notifica via e-mail 32 #+ al/i indirizzo/i del responsabile dell'ISP. 33 # Suggerimento: usate il comando "mail". 34 35 exit $? 36 37 # spam-lookup.sh chinatietong.com 38 # Un noto dominio di spam. 39 40 # "crnet_mgr@chinatietong.com" 41 # "crnet_tec@chinatietong.com" 42 # "postmaster@chinatietong.com" 43 44 45 # Per una versione piu' elaborata di questo script, 46 #+ vedi la pagina home di SpamViz , http://www.spamviz.net/index.html. 47 48 # * [N.d.T.] 49 # Record SOA (Start of Authority). e' ii record che contiene informazioni 50 #+ sulla zona e indica che il server e' "autoritativo" per quella zona. 51 Esempio 12-37. Analizzare un dominio di spam 1 #! /bin/bash 2 # is-spammer.sh: Identificare i domini di spam 3 4 # $Id: is-spammer, v 1.4 2004/09/01 19:37:52 mszick Exp $ 5 # La riga precedente indica l'ID del RCS. 6 # 7 # e' la versione semplificata dello script "is_spammer.bash 8 #+ presente nell'appendice Script Aggiuntivi. 9 10 # is-spammer 11 12 # Viene usato il programma esterno 'dig' 13 # Provato con la versione 9.2.4rc5 14 15 # Uso di funzioni. 16 # Utilizzo di IFS per il controllo delle stringhe da assegnare agli array. 17 # Fa persino qualcosa di utile: controlla le blacklist dei server e-mail. 18 19 # Si usa il nome.dominio presente nell'URL: 20 # http://www.veramente_ottimo.spammer.biz/tutto_il_resto_ignorato 21 # ^^^^^^^^^^^ 22 # Oppure il nome.domainio dell'indirizzo e-mail: 23 # Offerta_Strabiliante@spammer.biz 24 # 25 # come unico argomento dello script. 26 #(PS: occorre essere connessi ad internet) 27 # 28 # Concludendo, in base ai due esempi precedenti, questo script si invoca con: 29 # is-spammer.sh spammer.biz 30 31 32 # Spaziatura == :Spazio:Tabulazione:Line Feed:A_capo: 33 SPZ_IFS=$'\x20'$'\x09'$'\x0A'$'\x0D' 34 35 # Nessuna spaziatura == Line Feed:A_capo 36 No_SPZ=$'\x0A'$'\x0D' 37 38 # Separatore di campo per gli indirizzi ip puntati 39 IND_IFS=${No_SPZ}'.' 40 41 # Recupera la registrazione del testo del dns. 42 # rec_testo 43 rec_testo() { 44 45 # verifica $1 per l'assegnamento delle stringhe delimitate dai punti. 46 local -a dns 47 IFS=$IND_IFS 48 dns=( $1 ) 49 IFS=$SPZ_IFS 50 if [ "${dns[0]}" == '127' ] 51 then 52 # Controlla se vi e' una spiegazione. 53 echo $(dig +short $2 -t txt) 54 fi 55 } 56 57 # Recupera l'indirizzo dns. 58 # rec_idr 59 rec_idr() { 60 local risposta 61 local server 62 local causa 63 64 server=${1}${2} 65 risposta=$( dig +short ${server} ) 66 67 # Se la risposta contiene un codice d'errore . . . 68 if [ ${#risposta} -gt 6 ] 69 then 70 causa=$(rec_testo ${risposta} ${server} ) 71 causa=${causa:-${risposta}} 72 fi 73 echo ${causa:-' non in blacklist.'} 74 } 75 76 # Si deve risalire all'indirizzo IP partendo dal nome di dominio. 77 echo "Recupero l'indirizzo di: "$1 78 ip_idr=$(dig +short $1) 79 risposta_dns=${ip_idr:-' nessuna risposta '} 80 echo ' Indirizzo: '${risposta_dns} 81 82 # Una risposta valida deve essere formata da almeno 4 cifre e 3 punti. 83 if [ ${#ip_idr} -gt 6 ] 84 then 85 echo 86 declare richiesta 87 88 # Controllo per l'assegnamento delle stringhe tra i punti. 89 declare -a dns 90 IFS=$IND_IFS 91 dns=( ${ip_idr} ) 92 IFS=$SPZ_IFS 93 94 # Riordina gli ottetti nella sequenza adatta ad una interrogazione dns. 95 dns_inv="${dns[3]}"'.'"${dns[2]}"'.'"${dns[1]}"'.'"${dns[0]}"'.' 96 97 # Controlla su: http://www.spamhaus.org (Tradizionale, ben mantenuto) 98 echo -n 'spamhaus.org dice: ' 99 echo $(rec_idr ${dns_inv} 'sbl-xbl.spamhaus.org') 100 101 # Controlla su: http://ordb.org (Server aperti di istradamento e-mail) 102 echo -n ' ordb.org dice: ' 103 echo $(rec_idr ${dns_inv} 'relays.ordb.org') 104 105 # Controlla su: http://www.spamcop.net/ (Qui si possono segnalare gli spammer) 106 echo -n ' spamcop.net dice: ' 107 echo $(rec_idr ${dns_inv} 'bl.spamcop.net') 108 109 # # # altre operazioni di blacklist # # # 110 111 # Controlla su: http://cbl.abuseat.org. 112 echo -n ' abuseat.org dice: ' 113 echo $(rec_idr ${dns_inv} 'cbl.abuseat.org') 114 115 # Controlla su: http://dsbl.org/usage (Server vari di istradamento e-mail) 116 echo 117 echo 'Elenchi di server distibuiti' 118 echo -n ' list.dsbl.org dice: ' 119 echo $(rec_idr ${dns_inv} 'list.dsbl.org') 120 121 echo -n ' multihop.dsbl.org dice: ' 122 echo $(rec_idr ${dns_inv} 'multihop.dsbl.org') 123 124 echo -n 'unconfirmed.dsbl.org dice: ' 125 echo $(rec_idr ${dns_inv} 'unconfirmed.dsbl.org') 126 127 else 128 echo 129 echo 'Indirizzo inutilizzabile.' 130 fi 131 132 exit 0 133 134 # Esercizi: 135 # -------- 136 137 # 1) Verificate gli argomenti passati allo script, in caso d'errore 138 # l'esecuzione deve terminare con un messaggio appropriato. 139 140 # 2) Controllate l'avvenuta connessione internet prima dell'invocazione dello 141 # script, in caso contrario terminate con un appropriato messaggio d'errore. 142 143 # 3) Sostituite la "codifica" dei server BHL* con delle variabili generiche. 144 145 # 4) Impostate una temporizzazione per lo script usando l'opzione "+time=" 146 del comando 'dig'. 147 148 # * Black Hole Lists - Elenchi dei server di istradamento e-mail aperti che, 149 #+ come tali, sono utilizzati dagli spammer [N.d.T.]. Per un'ancor piu' elaborata versione dello script precedente, vedi Esempio A-27. 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 puo' 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. e' uno strumento diagnostico per verificare le connessioni di rete e dovrebbe essere usato con cautela. Un ping che ha avuto successo restituisce exit status 0. Questo puo' essere verificato in uno script. 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 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 12-36. finger Rintraccia informazioni sugli utenti di una rete. Opzionalmente, il comando puo' 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. 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 sono compresi in 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 velocita' 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 puo' essere automatizzata in uno script (vedi Esempio 17-6, Esempio A-4 ed Esempio A-13). uucp, uux, cu uucp: UNIX to UNIX copy - copia da UNIX a UNIX. e' 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 e' adatta o non e' 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. e' una specie di versione inferiore di telnet. Anche questo comando fa parte del pacchetto uucp. telnet Utility e protocollo di connessione ad host remoto. Cautela 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. 1 wget -p http://www.xyz23.com/file01.html 2 # L'opzione -p o --page-requisite consente a wget di rintracciare tutti i file 3 #+ necessari per visualizzare la pagina specificata. 4 5 wget -r ftp://ftp.xyz24.net/~bozo/project_files/ -O $SAVEFILE 6 # Segue l'opzione di ricorsivita' -r che recupera tutti i link 7 #+ presenti sul sito specificato. Esempio 12-38. Ottenere una quotazione di borsa 1 #!/bin/bash 2 # quote-fetch.sh: Scarica una quotazione di borsa. 3 4 5 E_NOPARAM=66 6 7 if [ -z "$1" ] # Si deve specificare il titolo (sigla) da cercare. 8 then echo "Utilizzo: `basename $0` codice_titolo" 9 exit $E_NOPARAM 10 fi 11 12 codice_titolo=$1 13 14 suffisso_file=.html 15 # Cerca un file HTML, per cui bisogna usare un nome appropriato. 16 URL='http://finance.yahoo.com/q?s=' 17 # Servizio finanziario di Yahoo, con suffisso di ricerca del titolo. 18 19 # -------------------------------------------------------------- 20 wget -O ${codice_titolo}${suffisso_file} "${URL}${codice_titolo}" 21 # -------------------------------------------------------------- 22 23 24 # Per vedere la cosa all'opera su http://search.yahoo.com: 25 # ----------------------------------------------------------- 26 # URL="http://search.yahoo.com/search?fr=ush-news&p=${query}" 27 # wget -O "$salvanomefile" "${URL}" 28 # ----------------------------------------------------------- 29 # Registra un elenco di importanti URL. 30 31 exit $? 32 33 # Esercizi: 34 # -------- 35 # 36 # 1) Aggiungete una verifica che confermi all'utente che esegue lo script 37 # l'avvenuto collegamento. 38 # (Suggerimento: confrontate l'output di 'ps -ax' con "ppp" o "connect." 39 # 40 # 2) Modificate lo script per scaricare il bollettino metereologico locale, 41 #+ fornendo come argomento il codice di avviamento postale. Vedi anche Esempio A-29 e Esempio A-30. lynx Il brower per il Web ed i file lynx puo' essere utilizzato all'interno di uno script (con l'opzione -dump) per recuperare un file dal Web o da un sito ftp in modalita' non-interattiva. 1 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 e' 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 (sinconizzazione da remoto), aggiorna (sincronizza) file tra due differenti macchine collegate in rete. bash$ rsync -a ~/dirsorgente/*txt /node1/sottodirectory/ Esempio 12-39. Aggiornare FC4 1 #!/bin/bash 2 # fc4upd.sh 3 4 # Autore dello script: Frank Wang. 5 # Con piccole modifiche di stile effettuate dall'autore de Guida ASB. 6 # Utilizzato in Guida ASB con il permesso dell'autore dello script. 7 8 9 # Scarica l'aggiornamento di Fedora 4 da un mirror usando rsync. 10 # Per risparmiare spazio, scarica solamente l'ultima versione di un pacchetto, 11 #+ nel caso ve ne sia piu' d'una. 12 13 URL=rsync://distro.ibiblio.org/fedora-linux-core/updates/ 14 # URL=rsync://ftp.kddilabs.jp/fedora/core/updates/ 15 # URL=rsync://rsync.planetmirror.com/fedora-linux-core/updates/ 16 17 DEST=${1:-/var/www/html/fedora/updates/} 18 LOG=/tmp/repo-update-$(/bin/date +%Y-%m-%d).txt 19 PID_FILE=/var/run/${0##*/}.pid 20 21 E_RETURN=65 # Nel caso succeda qualcosa di inatteso. 22 23 24 # Opzioni generali di rsync 25 # -r: download ricorsivo 26 # -t: tempo rimanente 27 # -v: verbose - dettaglio 28 29 OPZ="-rtv --delete-excluded --delete-after --partial" 30 31 # modello di inclusione per rsync 32 # La barra iniziale indica la verifica del percorso assoluto. 33 INCLUDE=( 34 "/4/i386/kde-i18n-Chinese*" 35 # ^ ^ 36 # e' necessario il quoting per evitare il globbing. 37 ) 38 39 40 # modello di escusione per rsync 41 # Commentate temporaneamente i pacchetti da non considerare usando "#" . . . 42 ESCLUDE=( 43 /1 44 /2 45 /3 46 /testing 47 /4/SRPMS 48 /4/ppc 49 /4/x86_64 50 /4/i386/debug 51 "/4/i386/kde-i18n-*" 52 "/4/i386/openoffice.org-langpack-*" 53 "/4/i386/*i586.rpm" 54 "/4/i386/GFS-*" 55 "/4/i386/cman-*" 56 "/4/i386/dlm-*" 57 "/4/i386/gnbd-*" 58 "/4/i386/kernel-smp*" 59 # "/4/i386/kernel-xen*" 60 # "/4/i386/xen-*" 61 ) 62 63 64 init () { 65 # Consente alla pipe dei comandi di visualizzare eventuali errori 66 #+ di rsync, es. stalled network. 67 set -o pipefail 68 69 TMP=${TMPDIR:-/tmp}/${0##*/}.$$ # Registra la lista aggiornata 70 #+ del download. 71 trap "{ 72 rm -f $TMP 2>/dev/null 73 }" EXIT # Cancella il file temporaneo 74 #+ all'uscita. 75 } 76 77 78 controlla_pid () { 79 # Verifica l'esistenza del processo. 80 if [ -s "$PID_FILE" ]; then 81 echo "Il file PID esiste?. Verifica ..." 82 PID=$(/bin/egrep -o "^[[:digit:]]+" $PID_FILE) 83 if /bin/ps --pid $PID &>/dev/null; then 84 echo "Trovato processo $PID. ${0##*/} in esecuzione!" 85 /usr/bin/logger -t ${0##*/} \ 86 "Trovato processo $PID. ${0##*/} in esecuzione!" 87 exit $E_RETURN 88 fi 89 echo "Processo $PID non trovato. Inizio un nuovo processo . . ." 90 fi 91 } 92 93 94 # Imposta l'intervallo dell'aggiornamento completo iniziando da root o da $URL, 95 #+ secondo quanto specificato nei modelli precedenti. 96 imposta_intervallo () { 97 include= 98 esclude= 99 for p in "${INCLUDE[@]}"; do 100 include="$include --include \"$p\"" 101 done 102 103 for p in "${ESCLUDE[@]}"; do 104 esclude="$esclude --exclude \"$p\"" 105 done 106 } 107 108 109 # Recupera e perfeziona l'elenco di aggiornamento rsync. 110 crea_lista () { 111 echo $$ > $PID_FILE || { 112 echo "Non posso scrivere nel file $PID_FILE" 113 exit $E_RETURN 114 } 115 116 echo -n "Recupero e perfezionamento della lista di aggiornamento . . ." 117 118 # Recupera la lista -- 'eval' e' necessario per far eseguire rsync 119 #+ come comando unico. 120 # $3 e $4 sono la data e l'ora di creazione del file. 121 # $5 e' il nome completo del pacchetto. 122 precedente= 123 pre_file= 124 pre_data=0 125 eval /bin/nice /usr/bin/rsync \ 126 -r $include $esclude $URL | \ 127 egrep '^dr.x|^-r' | \ 128 awk '{print $3, $4, $5}' | \ 129 sort -k3 | \ 130 { while read riga; do 131 # Calcola i secondi a partire da epoch per scartare i 132 #+ pacchetti obsoleti. 133 cor_data=$(date -d "$(echo $riga | awk '{print $1, $2}')" +%s) 134 # echo $cor_data 135 136 # Recupera il nome del file. 137 cor_file=$(echo $riga | awk '{print $3}') 138 # echo $cor_file 139 140 # Recupera il nome del pacchetto rpm dal nome del file, 141 #+ se possibile. 142 if [[ $cor_file == *rpm ]]; then 143 nome_pkg=$(echo $cor_file | sed -r -e \ 144 's/(^([^_-]+[_-])+)[[:digit:]]+\..*[_-].*$/\1/') 145 else 146 nome_pkg= 147 fi 148 # echo $nome_pkg 149 150 if [ -z "$nome_pkg" ]; then # Se non e' un file rpm, 151 echo $cor_file >> $TMP #+ lo accoda alla lista di download. 152 elif [ "$nome_pkg" != "$precedente" ]; then # Trovato un nuovo 153 #+ pacchetto. 154 echo $pre_file >> $TMP # Accoda il 155 #+ precedente. 156 precedente=$nome_pkg # Salva quello 157 #+ corrente. 158 pre_data=$cor_data 159 pre_file=$cor_file 160 elif [ "$cor_data" -gt "$pre_data" ]; then # Stesso pacchetto, 161 #+ ma piu' recente, 162 pre_data=$cor_data #+ aggiorna il 163 #+ puntatore precedente. 164 pre_file=$cor_file 165 fi 166 done 167 echo $pre_file >> $TMP # TMP ora contiene la 168 #+ lista COMPLETA e 169 #+ aggiornata. 170 # echo "subshell=$BASH_SUBSHELL" 171 172 } # Le parentesi graffe sono necessarie per consentire a 173 #+ "echo $pre_file >> $TMP" finale di rimanere nella stessa 174 #+ subshell ( 1 ) assiema all'intero ciclo. 175 176 RIT=$? # Recupera il codice di ritorno della pipe. 177 178 [ "$RIT" -ne 0 ] && { 179 echo "Recupero della lista fallito con codice $RET" 180 exit $E_RETURN 181 } 182 183 echo "fatto"; echo 184 } 185 186 # Download di rsync. 187 scarica_file () { 188 189 echo "In download..." 190 /bin/nice /usr/bin/rsync \ 191 $OPZ \ 192 --filter "merge,+/ $TMP" \ 193 --exclude '*' \ 194 $URL $DEST \ 195 | /usr/bin/tee $LOG 196 197 RIT=$? 198 199 # --filter merge,+/ e' cruciale allo scopo. 200 # + il modificatore significa includi e / percorso assoluto. 201 # Quindi, l'elenco ordinato presente in $TMP conterra' i nomi delle 202 #+ directory in ordine ascendente impedendo al successivo 203 #+ --exclude '*' di mandare tutto in "corto circuito." 204 205 echo "Fatto" 206 207 rm -f $PID_FILE 2>/dev/null 208 209 return $RIT 210 } 211 212 # ------- 213 # Main 214 init 215 controlla_pid 216 imposta_intervallo 217 crea_lista 218 scarica_file 219 RIT=$? 220 # ------- 221 222 if [ "$RIT" -eq 0 ]; then 223 /usr/bin/logger -t ${0##*/} "Fedora aggiornata con successo." 224 else 225 /usr/bin/logger -t ${0##*/} "Aggiornamento di Fedora fallito con codice: $RIT" 226 fi 227 228 exit $RIT 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 12-40. Uso di ssh 1 #!/bin/bash 2 # remote.bash: Uso di ssh. 3 4 # Esempio di Michael Zick. 5 # Usato con il consenso dell'autore. 6 7 8 # Presupposti: 9 # ----------- 10 # il df-2 non dev'esere stato impegnato ( '2>/dev/null' ). 11 # ssh/sshd presumono che lo stderr ('2') verra' visualizzato all'utente. 12 # 13 # sshd deve essere in esecuzione sulla macchina. 14 # Probabilmente questa e' la situazione per qualsiasi distribuzione 'standard', 15 #+ e senza aver fatto qualche strana impostazione di ssh-keygen. 16 17 # Provate ssh da riga di comando sulla vostra macchina: 18 # 19 # $ ssh $HOSTNAME 20 # Se non sono state fatte impostazioni ulteriori, vi verra' chiesta la password. 21 # inserite la password 22 # quindi $ exit 23 # 24 # Ha funzionato? In questo caso siete pronti per un altro po' di divertimento. 25 26 # Provate ssh come utente 'root': 27 # 28 # $ ssh -l root $HOSTNAME 29 # Quando vi verra' chiesta la password, inserite quella di root, non la vostra. 30 # Last login: Tue Aug 10 20:25:49 2004 from localhost.localdomain 31 # Dopo di che 'exit'. 32 33 # I comandi precedenti forniscono una shell interattiva. 34 # e' possibile impostare sshd in modalita' 'comando singolo', 35 #+ ma questo va oltre lo scopo dell'esempio. 36 # L'unica cosa da notare e' che quello che segue funziona 37 #+ in modalita' 'comando singolo'. 38 39 40 # Il fondamentale comando di visualizzazione allo stdout (locale). 41 42 ls -l 43 44 # E ora lo stesso comando su una macchina remota. 45 # Se desiderate, potete passare 'USERNAME' 'HOSTNAME' diversi: 46 USER=${USERNAME:-$(whoami)} 47 HOST=${HOSTNAME:-$(hostname)} 48 49 # Ora eseguiamo la precedente riga di comando su un host remoto, 50 #+ la trasmissione e' totalmente criptata. 51 52 ssh -l ${USER} ${HOST} " ls -l " 53 54 # Il risultato atteso e' l'elenco dei file della directory home dell'utente 55 #+ presente sulla macchina remota. 56 # Se volete vedere delle differenze, eseguite lo script da una qualsiasi directory 57 #+ diversa dalla vostra directory home. 58 59 # In altre parole, il comando Bash viene passato come stringa tra apici 60 #+ alla shell remota, che lo esegue sulla macchina remota. 61 # In questo caso sshd esegue ' bash -c "ls -l" ' per conto vostro. 62 63 # Per informazioni su argomenti quali il non dover inserire la 64 #+ password/passphrase ad ogni riga di comando, vedi 65 #+ man ssh 66 #+ man ssh-keygen 67 #+ man sshd_config. 68 69 exit 0 Cautela In un ciclo, ssh potrebbe causare un comportamento inaspettato. 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 funzionalita' di rcp, copia, cioe', 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 e' 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 puo' usare, naturalmente, il comando mesg per disabilitare l'accesso di write in scrittura su di un terminale. Poiché write e' 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). e' un comando nativo delle distribuzioni Linux 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 12-41. Uno script che si auto-invia 1 #!/bin/sh 2 # self-mailer.sh: Script che si auto-invia 3 4 adr=${1:-`whoami`} # Imposta l'utente corrente come predefinito, se 5 #+ non altrimenti specificato. 6 # Digitando 'self-mailer.sh wiseguy@superdupergenius.com' 7 #+ questo script viene inviato a quel destinatario. 8 # Il solo 'self-mailer.sh' (senza argomento) invia lo script alla 9 #+ persona che l'ha invocato, per esempio, bozo@localhost.localdomain 10 # 11 # Per i dettagli sul costrutto ${parametro:-default}, vedi la sezione 12 #+ "Sostituzione di Parametro" del capitolo "Variabili Riviste". 13 14 # ========================================================================= 15 cat $0 | mail -s " Lo script \"`basename $0`\" si e' auto-inviato." "$adr" 16 # ========================================================================= 17 18 # -------------------------------------------------- 19 # Saluti dallo script che si auto-invia. 20 # Una persona maliziosa ha eseguito questo script, 21 #+ che ne ha provocato l'invio a te. Apparentemente, 22 #+ certa gente non ha niente di meglio da fare 23 #+ con il proprio tempo. 24 # -------------------------------------------------- 25 26 echo "Il `date`, lo script \"`basename $0`\" e' stato inviato a "$adr"." 27 28 exit 0 bash$ printenv | grep HOME # Convertire in lettere maiuscole il contenuto di un file: dd if=$nomefile conv=ucase > $nomefile.maiuscolo # lcase # Per la conversione in minuscoloEsempio 12-54. Intercettare i tasti premuti 1 #!/bin/bash 2 # dd-keypress.sh: Intercetta i tasti premuti senza dover premere anche INVIO. 3 4 5 tastidapremere=4 # Numero di tasti da catturare. 6 7 8 precedenti_impostazioni_tty=$(stty -g) # Salva le precedenti 9 #+ impostazioni del terminale. 10 11 echo "Premi $tastidapremere tasti." 12 stty -icanon -echo # Disabilita la modalita' canonica. 13 # Disabilita l'eco locale. 14 tasti=$(dd bs=1 count=$tastidapremere 2> /dev/null) 15 # 'dd' usa lo stdin, se non viene specificato "fi" (file input). 16 17 stty "$precedenti_impostazioni_tty" # Ripristina le precedenti impostazioni. 18 19 echo "Hai premuto i tasti \"$tasti\"." 20 21 # Grazie a Stephane Chazelas per la dimostrazione. 22 exit 0 Comandi di sistema e d'amministrazione Gli script di avvio (startup) e di arresto (shutdown) presenti in /etc/rc.d illustrano gli usi (e l'utilita') di molti dei comandi che seguono. Questi, di solito, vengono invocati dall'utente root ed utilizzati per la gestione del sistema e per le riparazioni d'emergenza del filesystem. Vanno usati con attenzione poiché alcuni di questi comandi, se utilizzati in modo maldestro, possono danneggiare il sistema stesso. Utenti e gruppi users Visualizza tutti gli utenti presenti sul sistema. Equivale approssimativamente a who -q. groups Elenca l'utente corrente ed i gruppi a cui appartiene. Corrisponde alla variabile interna $GROUPS, ma, anziché indicare i gruppi con i numeri corrispondenti, li elenca con i loro nomi. bash$ groups bozita cdrom cdwriter audio xgrp bash$ echo $GROUPS 501 chown, chgrp Il comando chown modifica la proprieta' di uno o piu' file. Questo comando rappresenta un metodo utile che root puo' usare per spostare la proprieta' di un file da un utente all'altro. Un utente ordinario non puo' modificare la proprieta' dei file, neanche dei propri. [1] root# chown bozo *.txt Il comando chgrp modifica il gruppo proprietario di uno o piu' file. Occorre essere il proprietario del/dei file e membro del gruppo di destinazione (o root) per poter effettuare questa operazione. 1 chgrp --recursive dunderheads *.data 2 # Il gruppo "dunderheads" adesso e' proprietario di tutti i file"*.data" 3 #+ presenti nella directory $PWD (questo e' il significato di "recursive"). useradd, userdel Il comando d'amministrazione useradd aggiunge l'account di un utente al sistema e, se specificato, crea la sua directory home. Il corrispondente comando userdel cancella un utente dal sistema [2] ed i file ad esso associati. Nota Il comando adduser e' il sinonimo di useradd nonché, di solito, un link simbolico ad esso. usermod Modifica l'account di un utente. La variazione puo' riguardare la password, il gruppo d'appartenenza, la data di scadenza ed altri attributi dell'account di un determinato utente. Con questo comando e' possibile anche bloccare la password di un utente, con il risultato di disabilitare l'account dello stesso. groupmod Modifica gli attributi di un dato gruppo. Usando questo comando si puo' cambiare il nome del gruppo e/o il suo numero ID. id Il comando id elenca i reali ID utente e di gruppo dell'utente associato al processo corrente. e' il corrispettivo delle variabili interne $UID, $EUID e $GROUPS. bash$ id uid=501(bozo) gid=501(bozo) groups=501(bozo),22(cdrom),80(cdwriter),81(audio) bash$ echo $UID 501 Nota id mostra gli ID effettivi solo quando questi sono diversi da quelli reali. Vedi anche Esempio 9-5. who Visualizza tutti gli utenti connessi al sistema. bash$ who bozo tty1 Apr 27 17:45 bozo pts/0 Apr 27 17:46 bozo pts/1 Apr 27 17:47 bozo pts/2 Apr 27 17:49 L'opzione -m fornisce informazioni solo sull'utente corrente. Passare a who due argomenti, come nel caso di who am i o who The Man equivale a who -m. bash$ who -m localhost.localdomain!bozo pts/2 Apr 27 17:49 whoami e' simile a who -m, ma elenca semplicemente il nome dell'utente. bash$ whoami bozo w Visualizza tutti gli utenti connessi ed i processi di loro appartenenza. e' la versione estesa di who. L'output di w puo' essere collegato con una pipe a grep per la ricerca di un utente e/o processo specifico. bash$ w | grep startx bozo tty1 - 4:22pm 6:41 4.47s 0.45s startx logname Visualizza il nome di login dell'utente corrente (così come si trova in /var/run/utmp). Equivale, quasi, al precedente whoami. bash$ logname bozo bash$ whoami bozo Tuttavia... bash$ su Password: ...... bash# whoami root bash# logname bozo Nota Mentre logname visualizza il nome dell'utente connesso, whoami fornisce il nome dell'utente collegato al processo corrente. Come si e' appena visto, talvolta questi non coincidono. su Esegue un programma o uno script come utente diverso. su rjones esegue una shell come utente rjones. Il semplice su fa riferimento, in modo predefinito, all'utente root. Vedi Esempio A-15. sudo Esegue un comando come root (o altro utente). Puo' essere utilizzato in uno script, consentendone così l'esecuzione ad un utente ordinario. 1 #!/bin/bash 2 3 # Alcuni comandi. 4 sudo cp /root/secretfile /home/bozo/secret 5 # Ulteriori comandi. Il file /etc/sudoers contiene i nomi degli utenti autorizzati ad invocare sudo. passwd Imposta o modifica la password dell'utente. passwd puo' essere utilizzato in uno script, ma questo non dovrebbe essere fatto. Esempio 13-1. Impostare una nuova password 1 #!/bin/bash 2 # setnew-password.sh: A solo scopo dimostrativo. 3 # Non e' una buona idea eseguire veramente questo script. 4 # Deve essere eseguito da root. 5 6 UID_ROOT=0 # Root ha $UID 0. 7 E_UTENTE_ERRATO=65 # Non root? 8 9 E_UTENTE_INESISTENTE=70 10 SUCCESSO=0 11 12 13 if [ "$UID" -ne "$UID_ROOT" ] 14 then 15 echo; echo "Solo root puo' eseguire lo script."; echo 16 exit $E_UTENTE_ERRATO 17 else 18 echo 19 echo "Root, dovresti saper far di meglio che non eseguire questo script." 20 echo "Anche gli utenti root hanno le loro giornate storte... " 21 echo 22 fi 23 24 25 nomeutente=bozo 26 NUOVAPASSWORD=violazione_sicurezza 27 28 # Controlla se l'utente bozo esiste. 29 grep -q "$nomeutente" /etc/passwd 30 if [ $? -ne $SUCCESSO ] 31 then 32 echo "L'utente $nomeutente non esiste." 33 echo "Nessuna password modificata." 34 exit $E_UTENTE_INESISTENTE 35 fi 36 37 echo "$NUOVAPASSWORD" | passwd --stdin "$nomeutente" 38 # L'opzione '--stdin' di 'passwd' consente di 39 #+ ottenere la nuova password dallo stdin (o da una pipe). 40 41 echo; echo "E' stata cambiata la password dell'utente $nomeutente!" 42 43 # E' pericoloso usare il comando 'passwd' in uno script. 44 45 exit 0 Le opzioni -l, -u e -d del comando passwd consentono di bloccare, sbloccare e cancellare la password di un utente. Solamente root puo' usare queste opzioni. ac Visualizza la durata della connessione di un utente al sistema, letta da /var/log/wtmp. Questa e' una delle utility di contabilita' GNU. bash$ ac total 68.08 last Elenca gli ultimi utenti connessi, letti da /var/log/wtmp. Questo comando consente anche la visualizzazione dei login effettuati da remoto. Ad esempio, per visualizzare gli ultimi riavvii del sistema: bash$ last reboot reboot system boot 2.6.9-1.667 Fri Feb 4 18:18 (00:02) reboot system boot 2.6.9-1.667 Fri Feb 4 15:20 (01:27) reboot system boot 2.6.9-1.667 Fri Feb 4 12:56 (00:49) reboot system boot 2.6.9-1.667 Thu Feb 3 21:08 (02:17) . . . wtmp begins Tue Feb 1 12:50:09 2005 newgrp Modifica l'ID di gruppo dell'utente senza doversi disconnettere. Consente l'accesso ai file di un nuovo gruppo. Poiché gli utenti possono appartenere contemporaneamente a piu' gruppi, questo comando viene poco utilizzato. Terminali tty Visualizza il nome del terminale dell'utente corrente. e' da notare che ciascuna differente finestra di xterm viene considerata come un diverso terminale. bash$ tty /dev/pts/1 stty Mostra e/o modifica le impostazioni del terminale. Questo complesso comando, usato in uno script, riesce a controllare il comportamento del terminale e le modalita' di visualizzazione degli output. Si veda la sua pagina info e la si studi attentamente. Esempio 13-2. Abilitare un carattere di cancellazione 1 #!/bin/bash 2 # erase.sh: Uso di "stty" per impostare un carattere di cancellazione nella 3 #+ lettura dell'input. 4 5 echo -n "Come ti chiami? " 6 read nome # Provate ad usare il tasto di ritorno 7 #+ (backspace) per cancellare i caratteri 8 #+ digitati. Problemi?. 9 echo "Ti chiami $nome." 10 11 stty erase '#' # Imposta il carattere "hash" (#) come 12 #+ carattere di cancellazione. 13 echo -n "Come ti chiami? " 14 read nome # Usate # per cancellare l'ultimo carattere 15 #+ digitato. 16 echo "Ti chiami $nome." 17 18 # Attenzione: questa impostazione permane anche dopo l'uscita dallo script. 19 20 exit 0 Esempio 13-3. Password segreta: disabilitare la visualizzazione a terminale 1 #!/bin/bash 2 # secret-pw.sh: password segreta 3 4 echo 5 echo -n "Immetti la password " 6 read passwd 7 echo "La password e' $passwd" 8 echo -n "Se qualcuno stesse sbirciando da dietro le vostre spalle," 9 echo "la password sarebbe compromessa." 10 11 echo && echo # Due righe vuote con una "lista and". 12 13 stty -echo # Disabilita la visualizzazione sullo schermo. 14 15 echo -n "Reimmetti la password " 16 read passwd 17 echo 18 echo "La password e' $passwd" 19 echo 20 21 stty echo # Ripristina la visualizzazione sullo schermo. 22 23 exit 0 24 25 # Effettuate un 'info stty' per maggiori informazioni su questo utile, 26 #+ ma complesso, comando. Un uso creativo di stty e' quello di rilevare i tasti premuti dall'utente (senza dover premere successivamente INVIO). Esempio 13-4. Rilevamento dei tasti premuti 1 #!/bin/bash 2 # keypress.sh: Rileva i tasti premuti dall'utente ("tasti bollenti"). 3 4 echo 5 6 precedenti_impostazioni_tty=$(stty -g) # Salva le precedenti impostazioni 7 # (perché?). 8 stty -icanon 9 tasti=$(head -c1) # Oppure $(dd bs=1 count=1 2> /dev/null) 10 #+ su sistemi non-GNU 11 12 echo 13 echo "Hai premuto i tasti \""$tasti"\"." 14 echo 15 16 stty "$precedenti_impostazioni_tty" # Ripristina le precedenti impostazioni. 17 18 # Grazie, Stephane Chazelas. 19 20 exit 0 Vedi anche Esempio 9-3. terminali e modalita' Normalmente, un terminale lavora in modalita' canonica. Questo significa che quando un utente preme un tasto il carattere corrispondente non viene inviato immediatamente al programma in esecuzione in quel momento sul terminale. Tutti i tasti premuti vengono registrati in un buffer specifico per quel terminale. Solo quando l'utente preme il tasto INVIO i caratteri digitati, che sono stati salvati nel buffer, vengono inviati al programma in esecuzione. All'interno di ciascun terminale e' anche presente un elementare editor di linea. bash$ stty -a speed 9600 baud; rows 36; columns 96; line = 0; intr = ^C; quit = ^\; erase = ^H; kill = ^U; eof = ^D; eol = ; eol2 = ; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; ... isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt Utilizzando la modalita' canonica e' possibile ridefinire i tasti speciali dell'editor di riga del terminale. bash$ cat > filexxx whaIfoo barciao mondo bash$ cat filexxx ciao mondo bash$ wc -c < filexxx 11 Il processo che controlla il terminale riceve solamente 11 caratteri (10 alfabetici, piu' un ritorno a capo), sebbene l'utente abbia premuto 26 tasti. In modalita' non-canonica ("raw" - grezza), la pressione di ciascun tasto (compresi gli abbinamenti speciali come ctl-H) determina l'invio immediato del corrispondente carattere al processo di controllo. Il prompt di Bash disabilita sia icanon che echo, dal momento che sostituisce l'editor di riga del terminale con un suo editor piu' elaborato. Così, per esempio, se si digita ctl-A al prompt della shell, non viene visualizza ^A sullo schermo, Bash invece riceve il carattere \1, lo interpreta e sposta il cursore all'inizio della riga. Stéphane Chazelas setterm Imposta alcuni attributi del terminale. Questo comando scrive una stringa nello stdout del proprio terminale con la quale modifica il comportamento del terminale stesso. bash$ setterm -cursor off bash$ setterm puo' essere usato in uno script per modificare le modalita': di visualizzazione di un testo allo stdout, anche se esistono certamente strumenti migliori per questo scopo. 1 setterm -bold on 2 echo ciao in grassetto 3 4 setterm -bold off 5 echo ciao normale tset Mostra o inizializza le impostazioni del terminale. e' una versione meno potente di stty. bash$ tset -r Terminal type is xterm-xfree86. Kill is control-U (^U). Interrupt is control-C (^C). setserial Imposta o visualizza i parametri di una porta seriale. Questo comando deve essere eseguito dall'utente root e si trova, di solito, in uno script di avvio del sistema. 1 # Dallo script /etc/pcmcia/serial: 2 3 IRQ=`setserial /dev/$DEVICE | sed -e 's/.*IRQ: //'` 4 setserial /dev/$DEVICE irq 0 ; setserial /dev/$DEVICE irq $IRQ getty, agetty Il processo di inizializzazione di un terminale utilizza getty o agetty per l'impostazione del login di un utente. Questi comandi non vengono usati negli script di shell. Il loro corrispondente per lo scripting e' stty. mesg Abilita o disabilita l'accesso in scrittura al terminale dell'utente corrente. Disabilitando l'accesso si impedisce ad un altro utente della rete di scrivere su quel terminale. Suggerimento Puo' risultare molto fastidioso veder comparire improvvisamente un messaggio d'ordinazione di una pizza nel bel mezzo di un file di testo su cui si sta lavorando. Su una rete multi-utente, potrebbe essere desiderabile disabilitare l'accesso in scrittura al terminale quando si ha bisogno di evitare qualsiasi interruzione. wall e' l'acronimo di " write all", vale a dire, invia un messaggio ad ogni terminale di ciascun utente collegato alla rete. Si tratta, innanzi tutto, di uno strumento dell'amministratore di sistema, utile, per esempio, quando occorre avvertire tutti gli utenti che la sessione dovra' essere arrestata a causa di un determinato problema (vedi Esempio 17-1). bash$ wall Tra 5 minuti Il sistema verra' sospeso per manutenzione! Broadcast message from ecobel (pts/1) Sun Jul 8 13:53:27 2001... Tra 5 minuti il sistema verra' sospeso per manutenzione! Nota Se l'accesso in scrittura di un particolare terminale e' stato disabilitato con mesg, allora wall non potra' inviare nessun messaggio a quel terminale. Informazioni e statistiche uname Visualizza allo stdout le specifiche di sistema (SO, versione del kernel, ecc). Invocato con l'opzione -a, fornisce le informazioni in forma dettagliata (vedi Esempio 12-5). L'opzione -s mostra solo il tipo di Sistema Operativo. bash$ uname -a Linux localhost.localdomain 2.2.15-2.5.0 #1 Sat Feb 5 00:13:43 EST 2000 i686 unknown bash$ uname -s Linux arch Mostra l'architettura del sistema. Equivale a uname -m. Vedi Esempio 10-26. bash$ arch i686 bash$ uname -m i686 lastcomm Fornisce informazioni sui comandi precedentemente eseguiti, così come sono registrati nel file /var/account/pacct. Come opzioni si possono specificare il nome del comando e dell'utente. e' una delle utility di contabilita' GNU. lastlog Elenca l'ora dell'ultimo login di tutti gli utenti del sistema. Fa riferimento al file /var/log/lastlog. bash$ lastlog root tty1 Fri Dec 7 18:43:21 -0700 2001 bin **Never logged in** daemon **Never logged in** ... bozo tty1 Sat Dec 8 21:14:29 -0700 2001 bash$ lastlog | grep root root tty1 Fri Dec 7 18:43:21 -0700 2001 Cautela Il comando fallisce se l'utente che l'ha invocato non possiede i permessi di lettura sul file /var/log/lastlog. lsof Elenca i file aperti. Questo comando visualizza una tabella dettagliata di tutti i file aperti in quel momento e fornisce informazioni sui loro proprietari, sulle dimensioni, sui processi ad essi associati ed altro ancora. Naturalmente, lsof puo' essere collegato tramite una pipe a grep e/o awk per verificare ed analizzare il risultato. bash$ lsof COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME init 1 root mem REG 3,5 30748 30303 /sbin/init init 1 root mem REG 3,5 73120 8069 /lib/ld-2.1.3.so init 1 root mem REG 3,5 931668 8075 /lib/libc-2.1.3.so cardmgr 213 root mem REG 3,5 36956 30357 /sbin/cardmgr ... strace Strumento diagnostico e di debugging per il tracciamento dei segnali e delle chiamate di sistema. Il modo piu' semplice per invocarlo e' strace COMANDO. bash$ strace df execve("/bin/df", ["df"], [/* 45 vars */]) = 0 uname({sys="Linux", node="bozo.localdomain", ...}) = 0 brk(0) = 0x804f5e4 ... e' l'equivalente Linux del comando truss di Solaris. nmap Analizzatore delle porte di rete. Questo comando analizza un server per localizzare le porte aperte ed i servizi ad esse associati. e' un importante strumento per la sicurezza, per proteggere una rete contro tentativi di hacking. 1 #!/bin/bash 2 3 SERVER=$HOST # localhost.localdomain (127.0.0.1). 4 NUMERO_PORTA=25 # porta SMTP. 5 6 nmap $SERVER | grep -w "$NUMERO_PORTA" # Questa specifica porta e' aperta? 7 # grep -w verifica solamente la parola esatta, 8 #+ così, per esempio, non verra' verificata la porta 1025. 9 10 exit 0 11 12 # 25/tcp open smtp nc L'utility nc (netcat) e' uno strumento completo per la connessione e l'ascolto sulle porte TCP e UDP. Utile per la diagnostica e le prove, nonché per client e server HTTP basati su semplici script di cui ne e' la componente principale. bash$ nc localhost.localdomain 25 220 localhost.localdomain ESMTP Sendmail 8.13.1/8.13.1; Thu, 31 Mar 2005 15:41:35 -0700 Esempio 13-5. Verificare se su un server remoto e' in esecuzione identd 1 #! /bin/sh 2 ## Stessa funzionalita' di ident-scan di DaveG 3 #+ usando, pero', netcat. Oooh, come sara' inc***to. 4 ## Argomenti: porta di riferimento [porta porta porta ...] 5 ## Blocca stdout _e_ stderr. 6 ## 7 ## Vantaggi: esecuzione piu' lenta di ident-scan, con meno possibilita' 8 ##+ che l'inetd remoto si allarmi, e verifica i pochi demoni conosciuti in 9 ##+ esecuzione solo sulle porte specificate. 10 ## Svantaggi: le porte devono essere indicate solo con il loro nummero, output 11 ##+ striminzito e non funziona per servizi remoti provenienti da porte con 12 ##+ numerazione elevata. 13 # Autore dello script: Hobbit 14 # Usato in Guida ASB con il suo consenso. 15 16 # ------------------------------------------------------ 17 E_ERR_ARG=65 # Sono necessari almeno due argomenti. 18 DUE_PAUSE=2 # Durata dell'interruzione. 19 TRE_PAUSE=3 20 IDPORTA=113 # Porta di autenticazione "tap ident". 21 CAUS1=999 22 CAUS2=31337 23 TIMEOUT0=9 24 TIMEOUT1=8 25 TIMEOUT2=4 26 # ------------------------------------------------------ 27 28 case "${2}" in 29 "" ) echo "Specificate l'HOST e almeno un PORTA." ; exit $E_ERR_ARG ;; 30 esac 31 32 # Effettua un ping per vedere se "stanno" eseguendo identd. 33 nc -z -w $TIMEOUT0 "$1" $IDPORTA ||\ 34 { echo "Oops, $1 non ha in esecuzione identd." ; exit 0 ; } 35 # -z effettua una scansione dei demoni in ascolto. 36 # -w $TIMEOUT = Durata del tentativo di connessione. 37 38 # Genera un numero casuale per la porta di partenza. 39 PC=`expr $$ % $CAUS1 + $CAUS2` 40 41 BERS="$1" 42 shift 43 44 while test "$1" ; do 45 nc -v -w $TIMEOUT1 -p ${PC} "$BERS" ${1} < /dev/null > /dev/null & 46 PROC=$! 47 sleep $TRE_PAUSE 48 echo "${1},${PC}" | nc -w $TIMEOUT2 -r "$BERS" $IDPORTA 2>&1 49 sleep $DUE_PAUSE 50 51 # Assomiglia a uno scrip per lamer o cos'altro . . . ? 52 # Commento dell'autore de Guida ASB: "Non e' poi così male, 53 #+ a dire il vero, anzi, e' piuttosto 54 #+ intelligente." 55 56 kill -HUP $PROC 57 PC=`expr ${PC} + 1` 58 shift 59 done 60 61 exit $? 62 63 # Note: 64 # ---- 65 66 # Provate ad eseguire lo script dopo aver commentato la riga 33 67 #+ fornedo come argomenti "localhost.localdomain 25". 68 69 # Per ultedriori script d'esempio di Hobbit su 'nc', 70 #+ date uno sguardo alla documentazione nella directory: 71 #+ /usr/share/doc/nc-X.XX/scripts. Naturalmente, e' presente nel ben noto script di una sola riga del Dr. Andrew Tridgell in BitKeeper Affair: 1 echo clone | nc thunk.org 5000 > e2fsprogs.dat free Mostra, in forma tabellare, l'utilizzo della memoria e della cache. Il suo output si presta molto bene alle verifiche per mezzo di grep, awk o Perl. Il comando procinfo visualizza tutte quelle informazioni che non sono fornite da free, e molto altro. bash$ free total used free shared buffers cached Mem: 30504 28624 1880 15820 1608 16376 -/+ buffers/cache: 10640 19864 Swap: 68540 3128 65412 Per visualizzare la memoria RAM inutilizzata: bash$ free | grep Mem | awk '{ print $4 }' 1880 procinfo Ricava ed elenca informazioni e statistiche dallo pseudo-filesystem /proc. Fornisce un elenco molto ampio e dettagliato. bash$ procinfo | grep Bootup Bootup: Wed Mar 21 15:15:50 2001 Load average: 0.04 0.21 0.34 3/47 6829 lsdev Elenca i dispositivi, vale a dire, l'hardware installato. bash$ lsdev Device DMA IRQ I/O Ports ------------------------------------------------ cascade 4 2 dma 0080-008f dma1 0000-001f dma2 00c0-00df fpu 00f0-00ff ide0 14 01f0-01f7 03f6-03f6 ... du Mostra, in modo ricorsivo, l'utilizzo del (disco) file. Se non diversamente specificato, fa riferimento alla directory di lavoro corrente. bash$ du -ach 1.0k ./wi.sh 1.0k ./tst.sh 1.0k ./random.file 6.0k . 6.0k total df Mostra l'utilizzo del filesystem in forma tabellare. bash$ df Filesystem 1k-blocks Used Available Use% Mounted on /dev/hda5 273262 92607 166547 36% / /dev/hda8 222525 123951 87085 59% /home /dev/hda7 1408796 1075744 261488 80% /usr dmesg Elenca allo stdout tutti i messaggi generati durante la fase di boot del sistema. Utile per il "debugging" e per verificare quali driver di dispositivo sono installati e quali interrupt vengono utilizzati. L'output di dmesg puo', naturalmente, essere verificato con grep, sed o awk dall'interno di uno script. bash$ dmesg | grep hda Kernel command line: ro root=/dev/hda2 hda: IBM-DLGA-23080, ATA DISK drive hda: 6015744 sectors (3080 MB) w/96KiB Cache, CHS=746/128/63 hda: hda1 hda2 hda3 < hda5 hda6 hda7 > hda4 stat Fornisce ampie e dettagliate statistiche su un dato file (anche su una directory o su un file di dispositivo) o una serie di file. bash$ stat test.cru File: "test.cru" Size: 49970 Allocated Blocks: 100 Filetype: Regular File Mode: (0664/-rw-rw-r--) Uid: ( 501/ bozo) Gid: ( 501/ bozo) Device: 3,8 Inode: 18185 Links: 1 Access: Sat Jun 2 16:40:24 2001 Modify: Sat Jun 2 16:40:24 2001 Change: Sat Jun 2 16:40:24 2001 Se il file di riferimento non esiste, stat restituisce un messaggio d'errore. bash$ stat file_inesistente file_inesistente: No such file or directory vmstat Visualizza statistiche riguardanti la memoria virtuale. bash$ vmstat procs memory swap io system cpu r b w swpd free buff cache si so bi bo in cs us sy id 0 0 0 0 11040 2636 38952 0 0 33 7 271 88 8 3 89 netstat Mostra informazioni e statistiche sulla rete corrente, come le tabelle di routing e le connessioni attive. Questa utility accede alle informazioni presenti in /proc/net (Capitolo 27). Vedi Esempio 27-3. netstat -r equivale a route. bash$ netstat Active Internet connections (w/o servers) Proto Recv-Q Send-Q Local Address Foreign Address State Active UNIX domain sockets (w/o servers) Proto RefCnt Flags Type State I-Node Path unix 11 [ ] DGRAM 906 /dev/log unix 3 [ ] STREAM CONNECTED 4514 /tmp/.X11-unix/X0 unix 3 [ ] STREAM CONNECTED 4513 . . . uptime Mostra da quanto tempo il sistema e' attivo, con le relative statistiche. bash$ uptime 10:28pm up 1:57, 3 users, load average: 0.17, 0.34, 0.27 Nota Un valore di load average di 1 o minore indica che il sistema gestisce i processi immediatamente. Un load average maggiore di 1 significa che i processi vengono accodati. Quando load average oltrepassa il 3 vuol dire che le prestazioni del sistema sono degradate in maniera significativa. hostname Visualizza il nome host del sistema. Questo comando imposta il nome dell'host in uno script di avvio in /etc/rc.d (/etc/rc.d/rc.sysinit o simile). Equivale a uname -n e corrisponde alla variabile interna $HOSTNAME. bash$ hostname localhost.localdomain bash$ echo $HOSTNAME localhost.localdomain Simili al comando hostname sono domainname, dnsdomainname, nisdomainname e ypdomainname. Questi possono essere usati per visualizzare o impostare il DNS di sistema o il nome di dominio NIS/YP. Anche diverse opzioni di hostname svolgono queste funzioni. hostid Visualizza un identificatore numerico esadecimale a 32 bit dell'host della macchina. bash$ hostid 7f0100 Nota Si presume che questo comando possa fornire un numero di serie "unico" per un particolare sistema. Certe procedure per la registrazione di prodotto utilizzano questo numero per identificare una specifica licenza d'uso. Sfortunatamente, hostid restituisce solo l'indirizzo di rete della macchina in forma esadecimale con la trasposizione di una coppia di byte. L'indirizzo di rete di una tipica macchina Linux, non appartenente ad una rete, si trova in /etc/hosts. bash$ cat /etc/hosts 127.0.0.1 localhost.localdomain localhost Si da' il caso che, con la trasposizione dei byte di 127.0.0.1, si ottiene 0.127.1.0, che trasformato in esadecimale corrisponde a 007f0100, l'esatto equivalente di quanto e' stato restituito da hostid, come visto in precedenza. Solo che esistono alcuni milioni di altre macchine Linux con questo stesso hostid. sar L'esecuzione di sar (System Activity Report) fornisce un dettagliatissimo resoconto delle statistiche di sistema. Santa Cruz Operation (la "vecchia" SCO) ha rilasciato sar sotto licenza Open Source nel giugno 1999. Questo comando non fa parte delle distribuzioni di base di Linux, ma e' contenuto nel pacchetto sysstat utilities, scritto da Sebastien Godard. bash$ sar Linux 2.4.9 (brooks.seringas.fr) 09/26/03 10:30:00 CPU %user %nice %system %iowait %idle 10:40:00 all 2.21 10.90 65.48 0.00 21.41 10:50:00 all 3.36 0.00 72.36 0.00 24.28 11:00:00 all 1.12 0.00 80.77 0.00 18.11 Average: all 2.23 3.63 72.87 0.00 21.27 14:32:30 LINUX RESTART 15:00:00 CPU %user %nice %system %iowait %idle 15:10:00 all 8.59 2.40 17.47 0.00 71.54 15:20:00 all 4.07 1.00 11.95 0.00 82.98 15:30:00 all 0.79 2.94 7.56 0.00 88.71 Average: all 6.33 1.70 14.71 0.00 77.26 readelf Mostra informazioni e statistiche sul file elf specificato. Fa parte del pacchetto binutils. bash$ readelf -h /bin/bash ELF Header: Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 Class: ELF32 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: EXEC (Executable file) . . . size Il comando size [/percorso/del/binario] fornisce le dimensioni dei segmenti di un binario eseguibile o di un file archivio. e' usato soprattutto dai programmatori. bash$ size /bin/bash text data bss dec hex filename 495971 22496 17392 535859 82d33 /bin/bash Log di sistema logger Accoda messaggi generati dall'utente ai log di sistema (/var/log/messages). Non e' necessario essere root per invocare logger. 1 logger Riscontrata un'instabilita' nella connessione di rete alle 23:10, 21/05. 2 # Ora eseguite 'tail /var/log/messages'. Inserendo il comando logger in uno script e' possibile scrivere informazioni di debugging in /var/log/messages. 1 logger -t $0 -i Logging alla riga "$LINENO". 2 # L'opzione "-t" specifica l'identificativo della registrazione di logger 3 # L'opzione "-i" registra l'ID di processo. 4 5 # tail /var/log/message 6 # ... 7 # Jul 7 20:48:58 localhost ./test.sh[1712]: Logging alla riga 3. logrotate Questa utility gestisce i file di log di sistema, effettuandone la rotazione, la compressione, la cancellazione e/o l'invio per e-mail, secondo le necessita'. Questo evita che /var/log si riempia all'inverosimile di vecchi file di log. Di solito cron esegue logrotate a cadenza giornaliera. Aggiungendo una voce appropriata in /etc/logrotate.conf e' possibile gestire i file di log personali allo stesso modo di quelli di sistema. Nota Stefano Falsetto ha creato rottlog, che egli considera una versione migliorata di logrotate. Controllo dei job ps Statistiche di processo (Process Statistics): elenca i processi attualmente in esecuzione per proprietario e PID (ID di processo). Viene solitamente invocato con le opzioni ax e puo' essere collegato tramite una pipe a grep o sed per la ricerca di un processo specifico (vedi Esempio 11-12 e Esempio 27-2). bash$ ps ax | grep sendmail 295 ? S 0:00 sendmail: accepting connections on port 25 Per visualizzare graficamente i processi di sistema in forma di struttura ad "albero": ps afjx oppure ps ax --forest. pgrep, pkill Combinazione del comando ps con grep e kill. bash$ ps a | grep mingetty 2212 tty2 Ss+ 0:00 /sbin/mingetty tty2 2213 tty3 Ss+ 0:00 /sbin/mingetty tty3 2214 tty4 Ss+ 0:00 /sbin/mingetty tty4 2215 tty5 Ss+ 0:00 /sbin/mingetty tty5 2216 tty6 Ss+ 0:00 /sbin/mingetty tty6 4849 pts/2 S+ 0:00 grep mingetty bash$ pgrep mingetty 2212 mingetty 2213 mingetty 2214 mingetty 2215 mingetty 2216 mingetty pstree Elenca i processi attualmente in esecuzione in forma di struttura ad "albero" . L'opzione -p mostra i PID e i nomi dei processi. top Visualizza, in aggiornamento continuo, i processi maggiormente intensivi in termini di cpu. L'opzione -b esegue la visualizzazione in modalita' testo, di modo che l'output possa essere verificato o vi si possa accedere da uno script. bash$ top -b 8:30pm up 3 min, 3 users, load average: 0.49, 0.32, 0.13 45 processes: 44 sleeping, 1 running, 0 zombie, 0 stopped CPU states: 13.6% user, 7.3% system, 0.0% nice, 78.9% idle Mem: 78396K av, 65468K used, 12928K free, 0K shrd, 2352K buff Swap: 157208K av, 0K used, 157208K free 37244K cached PID USER PRI NI SIZE RSS SHARE STAT %CPU %MEM TIME COMMAND 848 bozo 17 0 996 996 800 R 5.6 1.2 0:00 top 1 root 8 0 512 512 444 S 0.0 0.6 0:04 init 2 root 9 0 0 0 0 SW 0.0 0.0 0:00 keventd ... nice Esegue un job sullo sfondo (background) con priorita' modificata. Le priorita' vanno da 19 (la piu' bassa) a -20 (la piu' alta). Solo root puo' impostare le priorita' negative (quelle piu' alte). Comandi correlati sono: renice, snice e skill. nohup Mantiene un comando in esecuzione anche dopo la disconnessione dell'utente. Il comando viene eseguito come un processo in primo piano (foreground) a meno che non sia seguito da &. Se si usa nohup in uno script, si prenda in considerazione di accoppiarlo a wait per evitare di creare un processo orfano o zombie. pidof Identifica l'ID di processo (PID) di un job in esecuzione. Poiché i comandi di controllo dei job, come kill e renice, agiscono sul PID di un processo (non sul suo nome), e' necessario identificare quel determinato PID. Il comando pidof e' approssimativamente simile alla variabile interna $PPID. bash$ pidof xclock 880 Esempio 13-6. pidof aiuta ad terminare un processo 1 #!/bin/bash 2 # kill-process.sh 3 4 NESSUNPROCESSO=2 5 6 processo=xxxyyyzzz # Si usa un processo inesistente. 7 # Solo a scopo dimostrativo... 8 # ... con questo script non si vuole terminare nessun processo in esecuzione. 9 # 10 # Se pero' voleste, per esempio, usarlo per scollegarvi da Internet, allora 11 # processo=pppd 12 13 t=`pidof $processo` # Cerca il pid (id di processo) di $processo. 14 # Il pid e' necessario a 'kill' (non si puo' usare 'kill' con 15 #+ il nome del programma). 16 17 if [ -z "$t" ] # Se il processo non e' presente, 'pidof' restituisce null. 18 then 19 echo "Il processo $processo non e' in esecuzione." 20 echo "Non e' stato terminato alcun processo." 21 exit $NESSUNPROCESSO 22 fi 23 24 kill $t # Potrebbe servire 'kill -9' per un processo testardo. 25 26 # Qui sarebbe necessaria una verifica, per vedere se il processo ha 27 #+ acconsentito ad essere terminato. 28 # Forse un altro " t=`pidof $processo` " oppure... 29 30 31 # L'intero script potrebbe essere sostituito da 32 # kill $(pidof -x nome_processo) 33 # ma non sarebbe stato altrettanto istruttivo. 34 35 exit 0 fuser Identifica i processi (tramite il PID) che hanno accesso ad un dato file, serie di file o directory. Puo' anche essere invocato con l'opzione -k che serve a terminare quei determinati processi. Questo ha interessanti implicazioni per la sicurezza, specialmente negli script che hanno come scopo quello di evitare, agli utenti non autorizzati, l'accesso ai servizi di sistema. bash$ fuser -u /usr/bin/vim /usr/bin/vim: 3207e(bozo) bash$ fuser -u /dev/null /dev/null: 3009(bozo) 3010(bozo) 3197(bozo) 3199(bozo) fuser si rivela un'applicazione importante nel momento in cui si devono inserire o rimuovere fisicamente dispositivi di memorizzazione, come i CD ROM o le memorie flash USB. Talvolta umount fallisce con il messaggio d'errore device is busy. Questo sta ad indicare che qualche utente e/o processo(i) hanno accesso a quel dispositivo. Un fuser -um /dev/nome_dispositivo vi rivelera' il mistero, così che possiate terminare tutti i processi coinvolti. bash$ umount /mnt/driveusb umount: /mnt/driveusb: device is busy bash$ fuser -um /dev/driveusb /mnt/driveusb: 1772c(bozo) bash$ kill -9 1772 bash$ umount /mnt/driveusb Il comando fuser, invocato con l'opzione -n identifica i processi che hanno accesso ad una determinata porta. Si rivela particolarmente utile in abbinamento con nmap. root# nmap localhost.localdomain PORT STATE SERVICE 25/tcp open smtp root# fuser -un tcp 25 25/tcp: 2095(root) root# ps ax | grep 2095 | grep -v grep 2095 ? Ss 0:00 sendmail: accepting connections cron Programma schedulatore d'amministrazione che esegue determinati compiti, quali pulire e cancellare i file di log di sistema ed aggiornare il database slocate. e' la versione superutente di at (sebbene ogni utente possa avere il proprio file crontab che puo' essere modificato con il comando crontab). Viene posto in esecuzione come demone ed esegue quanto specificato in /etc/crontab Nota Alcune distribuzioni Linux eseguono crond, la versione cron di Matthew Dillon. Controllo di processo e boot init Il comando init e' il genitore di tutti i processi. Richiamato nella parte finale della fase di boot, init determina il runlevel del sistema com'e' specificato nel file /etc/inittab. Viene invocato per mezzo del suo alias telinit e solo da root. telinit Link simbolico a init, rappresenta il mezzo per modificare il runlevel del sistema che, di solito, si rende necessario per ragioni di manutenzione dello stesso o per riparazioni d'emergenza del filesystem. Puo' essere invocato solo da root. Questo comando e' potenzialmente pericoloso - bisogna essere certi di averlo ben compreso prima di usarlo! runlevel Mostra il corrente e ultimo runlevel, ovvero se il sistema e' stato fermato (runlevel 0), se si trova in modalita' utente singolo (1), in modalita' multi-utente (2 o 3), in X Windows (5) o di riavvio (6). Questo comando ha accesso al file /var/run/utmp. halt, shutdown, reboot Serie di comandi per arrestare il sistema, solitamente prima dello spegnimento della macchina. service Avvia o arresta un servizio di sistema. Gli script di avvio (startup) presenti in /etc/init.d e in /etc/rc.d usano questo comando per attivare i servizi nella fase di boot. root# /sbin/service iptables stop Flushing firewall rules: [ OK ] Setting chains to policy ACCEPT: filter [ OK ] Unloading iptables modules: [ OK ] Rete ifconfig Utility per la configurazione e regolazione dell'interfaccia di rete. bash$ ifconfig -a lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:10 errors:0 dropped:0 overruns:0 frame:0 TX packets:10 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:700 (700.0 b) TX bytes:700 (700.0 b) ifconfig viene usato molto spesso in fase di boot per impostare le interfacce, o per disabilitarle in caso di riavvio. 1 # Frammenti di codice dal file /etc/rc.d/init.d/network 2 3 # ... 4 5 # Controlla se la rete e' attiva. 6 [ ${NETWORKING} = "no" ] && exit 0 7 8 [ -x /sbin/ifconfig ] || exit 0 9 10 # ... 11 12 for i in $interfaces ; do 13 if ifconfig $i 2>/dev/null | grep -q "UP" >/dev/null 2>&1 ; then 14 action "L'interfaccia $i non e' attiva: " ./ifdown $i boot 15 fi 16 # L'opzione "-q" di "grep", che e' una specifica GNU, significa 17 #+ "quiet", cioe', non produce output. 18 # Quindi, redirigere l'output in /dev/null non e' strettamente necessario. 19 20 # ... 21 22 echo "Attualmente sono attivi questi dispositivi:" 23 echo `/sbin/ifconfig | grep ^[a-z] | awk '{print $1}'` 24 # ^^^^^ 25 # si dovrebbe usare il quoting per evitare il globbing. 26 # Anche le forme seguenti vanno bene. 27 # echo $(/sbin/ifconfig | awk '/^[a-z]/ { print $1 })' 28 # echo $(/sbin/ifconfig | sed -e 's/ .*//') 29 # Grazie, S.C. per i commenti aggiuntivi. Vedi anche Esempio 29-6. iwconfig e' il comando predisposto per la configurazione di una rete wireless. e' l'equivalente wireless del precedente ifconfig, . route Mostra informazioni, o permette modifiche, alla tabella di routing del kernel. bash$ route Destination Gateway Genmask Flags MSS Window irtt Iface pm3-67.bozosisp * 255.255.255.255 UH 40 0 0 ppp0 127.0.0.0 * 255.0.0.0 U 40 0 0 lo default pm3-67.bozosisp 0.0.0.0 UG 40 0 0 ppp0 chkconfig Verifica la configurazione di rete. Il comando elenca e gestisce i servizi di rete presenti nella directory /etc/rc?.d avviati durante il boot. Trattandosi dell'adattamento fatto da Red Hat Linux dell'originario comando IRIX, chkconfig potrebbe non essere presente nell'installazione di base di alcune distribuzioni Linux. bash$ chkconfig --list atd 0:off 1:off 2:off 3:on 4:on 5:on 6:off rwhod 0:off 1:off 2:off 3:off 4:off 5:off 6:off ... tcpdump "Sniffa" i pacchetti di rete. e' uno strumento per analizzare e risolvere problemi di traffico sulla rete per mezzo del controllo delle intestazioni di pacchetto che verificano criteri specifici. Analizza gli ip dei pacchetti in transito tra gli host bozoville e caduceus: bash$ tcpdump ip host bozoville and caduceus Naturalmente, l'output di tcpdump puo' essere verificato usando alcune delle gia' trattate utility per l'elaborazione del testo. Filesystem mount Monta un filesystem, solitamente di un dispositivo esterno, come il floppy disk o il CDROM. Il file /etc/fstab fornisce un utile elenco dei filesystem, partizioni e dispositivi disponibili, con le relative opzioni, che possono essere montati automaticamente o manualmente. Il file /etc/mtab mostra le partizioni e i filesystem attualmente montati (compresi quelli virtuali, come /proc). mount -a monta tutti i filesystem e le partizioni elencate in /etc/fstab, ad eccezione di quelli con l'opzione noauto. Al boot uno script di avvio, presente in /etc/rc.d (rc.sysinit o qualcosa di analogo), invoca questo comando per montare tutto quello che deve essere montato. 1 mount -t iso9660 /dev/cdrom /mnt/cdrom 2 # Monta il CDROM 3 mount /mnt/cdrom 4 # Scorciatoia, se /mnt/cdrom e' elencato in /etc/fstab Questo versatile comando puo' persino montare un comune file su un dispositivo a blocchi, ed il file si comportera' come se fosse un filesystem. Mount riesce a far questo associando il file ad un dispositivo di loopback. Una sua possibile applicazione puo' essere quella di montare ed esaminare un'immagine ISO9660 prima di masterizzarla su un CDR. [3] Esempio 13-7. Verificare un'immagine CD 1 # Da root... 2 3 mkdir /mnt/cdtest # Prepara un punto di mount, nel caso non esistesse. 4 5 mount -r -t iso9660 -o loop cd-image.iso /mnt/cdtest # Monta l'immagine. 6 # l'opzione "-o loop" equivale a "losetup /dev/loop0" 7 cd /mnt/cdtest # Ora verifica l'immagine. 8 ls -alR # Elenca i file della directory. 9 # Eccetera. umount Smonta un filesystem attualmente montato. Prima di rimuovere fisicamente un floppy disk o un CDROM precedentemente montato, il dispositivo deve essere smontato, altrimenti si potrebbe ottenere, come risultato, la corruzione del filesystem. 1 umount /mnt/cdrom 2 # Ora potete premere il tasto eject e rimuovere in tutta sicurezza il disco. Nota L'utility automount, se correttamente installata, puo' montare e smontare i floppy disk e i CDROM nel momento in cui vi si accede o in fase di rimozione. Questa potrebbe, comunque, causare problemi sui portatili con dispositivi floppy e CDROM intercambiabili. sync Forza la scrittura immediata di tutti i dati aggiornati dai buffer all'hard disk (sincronizza l'HD con i buffer). Sebbene non strettamente necessario, sync assicura l'amministratore di sistema, o l'utente, che i dati appena modificati sopravviveranno ad un'improvvisa mancanza di corrente. Una volta, un sync; sync (due volte, tanto per essere assolutamente sicuri) era un'utile misura precauzionale prima del riavvio del sistema. A volte puo' essere desiderabile una pulizia immediata dei buffer, come nel caso della cancellazione di sicurezza di un file (vedi Esempio 12-55) o quando le luci di casa incominciano a tremolare. losetup Imposta e configura i dispositivi di loopback. Esempio 13-8. Creare un filesystem in un file 1 DIMENSIONE=1000000 # 1 mega 2 3 head -c $DIMENSIONE < /dev/zero > file # Imposta il file alla 4 #+ dimensione indicata. 5 losetup /dev/loop0 file # Lo imposta come dispositivo 6 #+ di loopback. 7 mke2fs /dev/loop0 # Crea il filesystem. 8 mount -o loop /dev/loop0 /mnt # Lo monta. 9 10 # Grazie, S.C. mkswap Crea una partizione o un file di scambio. L'area di scambio dovra' successivamente essere abilitata con swapon. swapon, swapoff Abilita/disabilita una partizione o un file di scambio. Questi comandi vengono solitamente eseguiti in fase di boot o di arresto del sistema. mke2fs Crea un filesystem Linux di tipo ext2. Questo comando deve essere invocato da root. Esempio 13-9. Aggiungere un nuovo hard disk 1 #!/bin/bash 2 3 # Aggiunge un secondo hard disk al sistema. 4 # Configurazione software. Si assume che l'hardware sia gia' montato sul PC. 5 # Da un articolo dell'autore di questo libro. 6 # Pubblicato sul nr. 38 di "Linux Gazette", http://www.linuxgazette.com. 7 8 ROOT_UID=0 # Lo script deve essere eseguito da root. 9 E_NONROOT=67 # Errore d'uscita non-root. 10 11 if [ "$UID" -ne "$ROOT_UID" ] 12 then 13 echo "Devi essere root per eseguire questo script." 14 exit $E_NONROOT 15 fi 16 17 # Da usare con estrema attenzione! 18 # Se qualcosa dovesse andare storto, potreste cancellare irrimediabilmente 19 #+ il filesystem corrente. 20 21 22 NUOVODISCO=/dev/hdb # Si assume che sia libero /dev/hdb. Verificate! 23 MOUNTPOINT=/mnt/nuovodisco # Oppure scegliete un altro punto di montaggio. 24 25 fdisk $NUOVODISCO 26 mke2fs -cv $NUOVODISCO1 # Verifica i blocchi difettosi visualizzando un 27 #+ output dettagliato. 28 # Nota: /dev/hdb1, *non* /dev/hdb! 29 mkdir $MOUNTPOINT 30 chmod 777 $MOUNTPOINT # Rende il nuovo disco accessibile a tutti gli utenti. 31 32 33 # Ora, una verifica... 34 # mount -t ext2 /dev/hdb1 /mnt/nuovodisco 35 # Provate a creare una directory. 36 # Se l'operazione riesce, smontate la partizione e procedete. 37 38 # Passo finale: 39 # Aggiungete la riga seguente in /etc/fstab. 40 # /dev/hdb1 /mnt/nuovodisco ext2 defaults 1 1 41 42 exit 0 Vedi anche Esempio 13-8 e Esempio 28-3. tune2fs Serve per la taratura di un filesystem di tipo ext2. Puo' essere usato per modificare i parametri del filesystem, come il numero massimo dei mount. Deve essere invocato da root. Attenzione Questo e' un comando estremamente pericoloso. Si usa a proprio rischio, perché si potrebbe inavvertitamente distruggere il filesystem. dumpe2fs Fornisce (elenca allo stdout) informazioni dettagliatissime sul filesystem. Dev'essere invocato da root. root# dumpe2fs /dev/hda7 | grep 'ount count' dumpe2fs 1.19, 13-Jul-2000 for EXT2 FS 0.5b, 95/08/09 Mount count: 6 Maximum mount count: 20 hdparm Elenca o modifica i parametri dell'hard disk. Questo comando va invocato da root e puo' risultare pericoloso se usato in modo maldestro. fdisk Crea o modifica la tabella delle partizioni di un dispositivo per la registrazione dei dati, di solito un hard disk. Dev'essere invocato da root. Attenzione Si utilizzi questo comando con estrema attenzione. Se qualcosa dovesse andare storto si potrebbe distruggere il filesystem. fsck, e2fsck, debugfs Serie di comandi per la verifica, riparazione e "debugging" del filesystem. fsck: front end per la verifica di un filesystem UNIX (puo' invocare altre utility). Il filesystem preimpostato, generalmente, e' di tipo ext2. e2fsck: esegue la verifica di un filesystem di tipo ext2. debugfs: per il "debugging" di un filesystem di tipo ext2. Uno degli usi di questo versatile, ma pericoloso, comando e' quello di (cercare di) recuperare i file cancellati. Solo per utenti avanzati! Cautela Tutti i precedenti comandi dovrebbero essere invocati da root e, se usati in modo scorretto, potrebbero danneggiare o distruggere il filesystem. badblocks Verifica i blocchi difettosi (difetti fisici) di un dispositivo di registrazione dati. Questo comando viene usato per formattare un nuovo hard disk installato o per verificare l'integrita' di un dispositivo per il backup. [4] Ad esempio, badblocks /dev/fd0 verifica il floppy disk. Il comando badblocks puo' essere invocato o in modalita' distruttiva (sovrascrittura di tutti i dati) o non distruttiva, in sola lettura. Se l'utente root possiede il dispositivo che deve essere verificato, com'e' di solito il caso, allora e' root che deve invocare questo comando. lsusb, usbmodules Il comando lsusb elenca tutti i bus USB (Universal Serial Bus) e i dispositivi ad essi collegati. Il comando usbmodules visualizza le informazioni sui moduli dei dispositivi USB collegati. root# lsusb Bus 001 Device 001: ID 0000:0000 Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 1.00 bDeviceClass 9 Hub bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 8 idVendor 0x0000 idProduct 0x0000 . . . mkbootdisk Crea un dischetto di boot che puo' essere usato per avviare il sistema se, per esempio, il MBR (master boot record) si e' corrotto. Il comando mkbootdisk, in realta', e' uno script Bash scritto da Erik Troan che si trova nella directory /sbin. chroot Cambia la directory ROOT (CHange ROOT). Normalmente i percorsi dei comandi relativi a /, la directory root predefinita, vengono forniti da $PATH. Questo comando cambia la directory root predefinita in un'altra (che diventa anche la directory di lavoro corrente). e' utile per motivi di sicurezza, ad esempio quando l'amministratore di sistema desidera limitare l'attivita' di certi utenti, come quelli che stanno usando telnet, ad una porzione sicura del filesystem (talvolta si fa riferimento a questa azione come "confinare un utente in una prigione, o gabbia, chroot"). Si noti che dopo un chroot l'originario percorso degli eseguibili di sistema non e' piu' valido. Il comando chroot /opt dovrebbe cambiare il riferimento da /usr/bin in /opt/usr/bin. Allo stesso modo, chroot /aaa/bbb /bin/ls dovrebbe redirigere le successive chiamate di ls a /aaa/bbb come directory base, al posto di / com'e' normalmente il caso. La riga alias XX 'chroot /aaa/bbb ls' inserita nel file ~/.bashrc di un utente, delimita la porzione di filesystem (/aaa/bbb) sulla quale quell'utente puo' eseguire il comando "XX". Il comando chroot e' anche utile durante l'esecuzione da un dischetto di boot d'emergenza (chroot a /dev/fd0), o come opzione di lilo in caso di ripristino dopo un crash del sistema. Altri usi comprendono l'installazione da un filesystem diverso (un'opzione rpm) o l'esecuzione di un filesystem in sola lettura da CDROM. Va invocato solo da root ed usato con attenzione. Cautela Potrebbe rendersi necessario copiare alcuni file di sistema nella directory indicata a chroot perché, dopo, non ci si potra' piu' basare sull'usuale variabile $PATH. lockfile Questa utility fa parte del pacchetto procmail (www.procmail.org). Serve a creare un file lock, un semaforo che controlla l'accesso ad un file, ad un dispositivo o ad una risorsa. Il file lock sta ad indicare che quel particolare file, dispositivo o risorsa e' utilizzato da un determinato processo ("busy") e questo consente un accesso limitato (o nessun accesso) ad altri processi. 1 lockfile /home/bozo/lockfiles/$0.lock 2 # Crea un file lock, protetto in scrittura, con lo stesso nome dello script. I file lock vengono utilizzati, ad esempio, per proteggere le cartelle di posta di sistema da modifiche fatte simultaneamente da piu' utenti, per indicare che si e' avuto accesso ad una porta modem o per mostrare che un'istanza di Netscape sta usando la sua cache. e' possibile, per mezzo di script, accertarsi dell'esistenza di un file lock creato da un certo processo, per verificare se quel processo e' ancora in esecuzione. Si noti che se uno script cerca di creare un file lock gia' esistente, lo script, probabilmente, si blocchera'. Normalmente, le applicazioni creano e verificano i file lock nella directory /var/lock. [5] Uno script puo' accertarsi della presenza di un file lock con qualcosa di simile a quello che segue. 1 nomeapplicazione=xyzip 2 # L'applicazione "xyzip" ha creato il file lock "/var/lock/xyzip.lock". 3 4 if [ -e "/var/lock/$nomeapplicazione.lock" ] 5 6 then 7 ... flock flock e' molto meno utile di lockfile. Imposta un lock d'"avvertimento" su un file, quindi esegue un comando. Questo impedisce ad un altro processo di impostare un lock su quel file finché il comando specificato non ha terminato il proprio compito. 1 flock $0 cat $0 > filelock__$0 2 # Imposta un lock sullo script in cui appare la riga precedente, 3 #+ per la durata della visualizzazione dello script allo stdout. Nota Al contrario di lockfile, flock non crea automaticamente un file lock. mknod Crea file di dispositivo a blocchi o a caratteri (potrebbe essere necessario per l'installazione di nuovo hardware sul sistema). L'utility MAKEDEV possiede tutte le funzionalita' di mknod ed e' piu' facile da usare. MAKEDEV Utility per la creazione di file di dispositivo. Deve essere eseguita da root e ci si deve trovare nella directory /dev. root# ./MAKEDEV e' una specie di versione avanzata di mknod. tmpwatch Cancella automaticamente i file a cui non si e' acceduto da un determinato periodo di tempo. e' invocato, di solito, da crond per cancellare vecchi file di log. Backup dump, restore Il comando dump e' un'elaborata utility per il backup del filesystem e viene generalmente usata su installazioni e reti di grandi dimensioni. [6] Legge le partizioni del disco e scrive un file di backup in formato binario. I file di cui si deve eseguire il backup possono essere salvati su dispositivi di registrazione piu' vari, compresi dischi e dispositivi a nastro. Il comando restore ripristina i backup effettuati con dump. fdformat Esegue una formattazione a basso livello di un dischetto. Risorse di sistema ulimit Imposta un limite superiore all'uso delle risorse di sistema. Viene solitamente invocato con l'opzione -f, che imposta la dimensione massima del file (ulimit -f 1000 limita la dimensione massima dei file a 1 mega). L'opzione -t imposta il limite dei file core (ulimit -c 0 elimina i file core). Di norma, il valore di ulimit dovrebbe essere impostato nel file /etc/profile e/o ~/.bash_profile (vedi Appendice G). Importante Un uso giudizioso di ulimit puo' proteggere il sistema contro una temibile bomba fork. 1 #!/bin/bash 2 # Script a solo scopo illustrativo. 3 # L'esecuzione e' a vostro rischio -- vi *blocchera'* il sistema. 4 5 while true # Ciclo infinito. 6 do 7 $0 & # Lo script invoca se stesso . . . 8 #+ genera il processo un numero infinito di volte . . . 9 #+ finché il sistema non si blocca a seguito 10 #+ dell'esaurimento di tutte le risorse. 11 done # Questo e' il famigerato scenario dell'"apprendista stregone". 12 13 exit 0 # Non esce qui, perché questo script non terminera' mai. La riga ulimit -Hu XX (dove XX e' il limite del processo utente), inserita nel file /etc/profile, avrebbe fatto abortire lo script appena lo stesso avesse superato il suddetto limite. quota Visualizza le quote disco dell'utente o del gruppo. setquota Imposta, da riga di comando, le quote disco di un utente o di un gruppo. umask Maschera per per l'impostazione dei permessi sui file dell'utente. Limita gli attributi predefiniti dei file di un particolare utente. Tutti i file creati da quell'utente otterranno gli attributi specificati con umask. Il valore (ottale) passato ad umask definisce i permessi disabilitati del file. Per esempio, umask 022 fa sì che i nuovi file avranno al massimo i permessi 755 (777 NAND 022). [7] Naturalmente l'utente potra', successivamente, modificare gli attributi di file particolari con chmod. e' pratica corrente impostare il valore di umask in /etc/profile e/o ~/.bash_profile (vedi Appendice G). Esempio 13-10. Usare umask per celare l'output di un file da occhi indagatori 1 #!/bin/bash 2 # rot13a.sh: Uguale allo script "rot13.sh", 3 #+ ma scrive l'output in un file "sicuro". 4 5 # Utilizzo: ./rot13a.sh nomefile 6 # o ./rot13a.sh $FILEOUT 18 # ^^Input dallo stdin o da un file.^^^^^^^^^^ Output rediretto in un file. 19 20 exit 0 rdev Fornisce informazioni o esegue modifiche sulla partizione di root, sullo spazio di scambio (swap) o sulle modalita' video. Le sue funzionalita' sono state, in genere, superate da lilo, ma rdev resta utile per impostare un ram disk. Questo comando, se usato male, e' pericoloso. Moduli lsmod Elenca i moduli del kernel installati. bash$ lsmod Module Size Used by autofs 9456 2 (autoclean) opl3 11376 0 serial_cs 5456 0 (unused) sb 34752 0 uart401 6384 0 [sb] sound 58368 0 [opl3 sb uart401] soundlow 464 0 [sound] soundcore 2800 6 [sb sound] ds 6448 2 [serial_cs] i82365 22928 2 pcmcia_core 45984 0 [serial_cs ds i82365] Nota Le stesse informazioni si ottengono con cat /proc/modules. insmod Forza l'installazione di un modulo del kernel (quando e' possibile e' meglio usare modprobe). Deve essere invocato da root. rmmod Forza la disinstallazione di un modulo del kernel. Deve essere invocato da root. modprobe Carica i moduli ed e', solitamente, invocato automaticamente in uno script di avvio. Deve essere invocato da root. depmod Crea il file delle dipendenze dei moduli, di solito invocato da uno script di avvio. modinfo Visualizza informazioni su un modulo caricabile. bash$ modinfo hid filename: /lib/modules/2.4.20-6/kernel/drivers/usb/hid.o description: "USB HID support drivers" author: "Andreas Gal, Vojtech Pavlik " license: "GPL" Miscellanea env Esegue un programma, o uno script, impostando o modificando determinate variabili d'ambiente (senza dover modificare l'intero ambiente del sistema). [nomevariabile=xxx] consente di modificare la variabile d'ambiente nomevariabile per la durata dello script. Se non viene specificata nessuna opzione, questo comando elenca le impostazioni di tutte le variabili d'ambiente. Nota In Bash e in altre shell derivate dalla Bourne, e' possibile impostare le variabili nell'ambiente di un singolo comando. 1 var1=valore1 var2=valore2 comandoXXX 2 # $var1 e $var2 vengono impostate solo nell'ambiente di 'comandoXXX'. Suggerimento e' possibile usare env nella prima riga di uno script (la c.d.riga "sha-bang") quando non si conosce il percorso della shell o dell'interprete. 1 #! /usr/bin/env perl 2 3 print "Questo script Perl verra' eseguito,\n"; 4 print "anche quando non sai dove si trova l'interprete Perl.\n"; 5 6 # Ottimo per la portabilita' degli script su altre piattaforme, 7 # dove i binari Perl potrebbero non essere dove ci aspettiamo. 8 # Grazie, S.C. ldd Mostra le dipendenze delle librerie condivise di un file eseguibile. bash$ ldd /bin/ls libc.so.6 => /lib/libc.so.6 (0x4000c000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x80000000) watch Esegue un comando ripetutamente, ad intervalli di tempo specificati. Gli intervalli preimpostati sono di due secondi, ma questo valore puo' essere modificato mediante l'opzione -n. 1 watch -n 5 tail /var/log/messages 2 # Visualizza la parte finale del file di log di sistema /var/log/messages 3 #+ ogni cinque secondi. strip Rimuove i riferimenti simbolici per il "debugging" da un binario eseguibile. Questo diminuisce la sua dimensione, ma rende il "debugging" impossibile. Questo comando si trova spesso nei Makefile, ma raramente in uno script di shell. nm Elenca i riferimenti simbolici, se non tolti con strip, presenti in un binario compilato. rdist Client per la distribuzione remota di file: sincronizza, clona o esegue il backup di un filesystem su un server remoto. 13.1. Analisi di uno script di sistema Utilizzando le conoscenze fin qui conseguite sui comandi d'amministrazione, ora si passa all'esame di uno script di sistema. Uno dei piu' brevi e piu' semplici da capire e' killall che e' utilizzato per sospendere i processi nella fase di arresto del sistema. Esempio 13-11. killall, da /etc/rc.d/init.d 1 #!/bin/sh 2 3 # --> I commenti aggiunti dall'autore del libro sono indicati con "# -->". 4 5 # --> Questo fa parte del pacchetto di script 'rc' 6 # --> di Miquel van Smoorenburg, 7 8 # --> Sembra che questo particolare script sia specifico di Red Hat 9 # --> (potrebbe non essere presente in altre distribuzioni). 10 11 # Bring down all unneeded services that are still running (there shouldn't 12 #+ be any, so this is just a sanity check) 13 14 for i in /var/lock/subsys/*; do 15 # --> Ciclo standard for/in, ma poiché "do" e' posto sulla stessa riga, 16 # --> e' necessario aggiungere il ";". 17 # Check if the script is there. 18 [ ! -f $i ] && continue 19 # --> Ecco un uso intelligente di una "lista and", equivale a: 20 # --> if [ ! -f "$i" ]; then continue 21 22 # Get the subsystem name. 23 subsys=${i#/var/lock/subsys/} 24 # --> Imposta la variabile, in questo caso, al nome del file. 25 # --> e' l'equivalente esatto di subsys=`basename $i`. 26 27 # --> Viene ricavato dal nome del file lock (se esiste un file lock 28 # -->+ che rappresenta la prova che il processo e' in esecuzione). 29 # --> Vedi la precedente voce "lockfile". 30 31 32 # Bring the subsystem down. 33 if [ -f /etc/rc.d/init.d/$subsys.init ]; then 34 /etc/rc.d/init.d/$subsys.init stop 35 else 36 /etc/rc.d/init.d/$subsys stop 37 # --> Sospende i job ed i demoni in esecuzione. 38 # --> E' da notare che "stop" e' un parametro posizionale, 39 # -->+ non un builtin di shell. 40 fi 41 done