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