Guida avanzata di scripting Bash: Un'approfondita esplorazione dell'arte dello scripting di shell | ||
---|---|---|
Indietro | Avanti |
Si pensi a /dev/null come a un "buco nero". Equivale, quasi, ad un file in sola scrittura. Tutto quello che vi viene scritto scompare per sempre. I tentativi per leggerne o visualizzarne il contenuto non danno alcun risultato. Ciò nonostante, /dev/null può essere piuttosto utile sia da riga di comando che negli script.
Sopprimere lo stdout.
cat $nomefile >/dev/null # Il contenuto del file non verrà visualizzato allo stdout. |
Sopprimere lo stderr (da Esempio 15-3).
rm $nomestrano 2>/dev/null # Così i messaggi d'errore [stderr] vengono "sotterrati". |
Sopprimere gli output di entrambi, stdout e stderr.
cat $nomefile 2>/dev/null >/dev/null # Se "$nomefile" non esiste, come output non ci sarà alcun messaggio d'errore. # Se "$nomefile" esiste, il suo contenuto non verrà visualizzato allo stdout. # Quindi, la riga di codice precedente, in ogni caso, non dà alcun risultato. # # Ciò può rivelarsi utile in situazioni in cui è necessario verificare il #+ codice di ritorno di un comando, ma non si desidera visualizzarne l'output. # # cat $nomefile &>/dev/null # anche in questa forma, come ha sottolineato Baris Cicek. |
Cancellare il contenuto di un file, preservando il file stesso ed i rispettivi permessi (da Esempio 2-1 e Esempio 2-3):
cat /dev/null > /var/log/messages # : > /var/log/messages ha lo stesso effetto e non genera un nuovo processo. cat /dev/null > /var/log/wtmp |
Svuotare automaticamente un file di log (ottimo specialmente per trattare quei disgustosi "cookie" inviati dai siti di commercio sul Web):
Come /dev/null, anche /dev/zero è uno pseudo file, ma in realtà genera un flusso di null (zeri binari, non del genere ASCII). Un output scritto in /dev/zero scompare, ed è abbastanza difficile leggere i null reali contenuti nel file, sebbene questo possa essere fatto con od o con un editor esadecimale. L'uso principale di /dev/zero è quello di creare un file fittizio inizializzato, di dimensione predeterminata, da usare come file di scambio (swap) temporaneo.
Esempio 28-2. Impostare un file di swap usando /dev/zero
#!/bin/bash # Creare un file di swap. UID_ROOT=0 # Root ha $UID 0. E_ERR_UTENTE=65 # Non root? FILE=/swap DIMENSIONEBLOCCO=1024 BLOCCHIMIN=40 SUCCESSO=0 # Questo script deve essere eseguito da root. if [ "$UID" -ne "$UID_ROOT" ] then echo; echo "Devi essere root per eseguire questo script."; echo exit $E_ERR_UTENTE fi blocchi=${1:-$BLOCCHIMIN} # Imposta a 40 blocchi il valore predefinito, se #+ non viene specificato diversamente da riga di #+ comando. # Equivale al seguente blocco di codice. # -------------------------------------------------- # if [ -n "$1" ] # then # blocchi=$1 # else # blocchi=$BLOCCHIMIN # fi # -------------------------------------------------- if [ "$blocchi" -lt $BLOCCHIMIN ] then blocchi=$BLOCCHIMIN # La dimensione deve essere di almeno 40 blocchi. fi ###################################################################### echo "Creazione di un file di swap della dimensione di $bloccchi blocchi (KB)." dd if=/dev/zero of=$FILE bs=$DIMENSIONEBLOCCO count=$blocchi # Pone il file a #+ zero. mkswap $FILE $blocchi # Lo designa come file di swap. swapon $FILE # Attiva il file di swap. # È da notate che se uno o più dei precedenti comandi dovesse fallire, #+ questo potrebbe causare dei problemi pericolosi. ###################################################################### # Esercizio: # Riscrivete il precedente blocco di codice in modo che, #+ in caso di fallita esecuzione, vengano eseguite le seguenti azioni: # 1) invio di un messaggio d'errore allo stderr, # 2) cancellazione di tutti i file temporanei, e # 3) uscita dallo script nella modalità consueta ma con un #+ appropriato codice d'errore. echo "Il file di swap è stato creato ed attivato." exit $SUCCESSO |
Un'altra applicazione di /dev/zero è quella di "svuotare" un file della dimensione indicata da usare per uno scopo specifico, come montare un filesystem su un dispositivo di loopback (vedi Esempio 16-8) o per la cancellazione di "sicurezza" di un file (vedi Esempio 15-55).
Esempio 28-3. Creare un ramdisk
#!/bin/bash # ramdisk.sh # Un "ramdisk" è un segmento della memoria RAM #+ che si comporta come se fosse un filesystem. # Presenta il vantaggio di un accesso velocissimo (tempo di lettura/scrittura) # Svantaggi: volatilità, perdita di dati al riavvio o in caso di mancanza di #+ corrente elettrica, meno RAM disponibile al sistema. # # Cos'ha di buono un ramdisk? # Tenere una serie elevata di dati, come una tabella o un dizionario, #+ su un ramdisk ne velocizza la consultazione, perché l'accesso #+ alla memoria è molto più veloce di un accesso al disco. E_NON_ROOT=70 # Deve essere eseguito da root. NOME_ROOT=root MOUNTPT=/mnt/ramdisk DIMENSIONE=2000 # 2K blocchi (modificare in base alle esigenze) DIMENSIONEBLOCCO=1024 # 1K (1024 byte) DISPOSITIVO=/dev/ram0 # Primo dispositivo ram nomeutente=`id -nu` if [ "$nomeutente" != "$NOME_ROOT" ] then echo "Devi essere root per eseguire \"`basename $0`\"." exit $E_NON_ROOT fi if [ ! -d "$MOUNTPT" ] # Verifica se già esiste il punto di mount, then #+ in modo che non ci sia un errore se lo script mkdir $MOUNTPT #+ viene eseguito più volte. fi ############################################################################## dd if=/dev/zero of=$DISPOSITIVO count=$DIMENSIONE bs=$DIMENSIONEBLOCCO # Pone il dispositivo RAM a zero. # Perché questa operazione è necessaria? mke2fs $DISPOSITIVO # Crea, su di esso, un filesystem di tipo ext2. mount $DISPOSITIVO $MOUNTPT # Lo monta. chmod 777 $MOUNTPT # Abilita l'accesso al ramdisk da parte di un #+ utente ordinario. # Tuttavia, si deve essere root per smontarlo. ############################################################################## # Occorre verificare se i precedenti comandi hanno avuto successo, #+ altrimenti potrebbero verificarsi dei problemi. # Esercizio: modificate lo script per renderlo più sicuro. echo "\"$MOUNTPT\" ora è disponibile all'uso." # Il ramdisk è accessibile, per la registrazione di file, anche ad un utente #+ ordinario. # Attenzione, il ramdisk è volatile e il contenuto viene perso #+ in caso di riavvio del PC o mancanza di corrente. # Copiate tutto quello che volete salvare in una directory regolare. # Dopo un riavvio, rieseguite questo script per reimpostare il ramdisk. # Rifare il mount di /mnt/ramdisk senza gli altri passaggi è inutile. # Opportunamente modificato, lo script può essere invocato in #+ /etc/rc.d/rc.local per impostare automaticamente un ramdisk in fase di boot. # Potrebbe essere appropriato, ad esempio, su un server database. exit 0 |
In aggiunta a quanto detto sopra, /dev/zero è richiesto dai binari ELF.