Perché dovresti cat / dev / null su qualcosa?
Lo farai per troncare il contenuto di un file mantenendo intatto l'inode. Tutti i programmi che hanno quel file aperto per la lettura o la scrittura non sarebbero interessati al di fuori del fatto che la dimensione del file sarebbe ripristinata a zero.
Un'alternativa fasulla che si trova spesso è rimuovere il file e poi crearlo nuovamente:
rm file
touch file
o simili:
mv file file.old
gzip file.old
touch file
Il problema è che questi metodi non impediscono che il vecchio file venga mantenuto da qualsiasi processo che abbia il file eliminato aperto al momento della cancellazione. Il motivo per cui è nei file system Unix, quando si elimina un file, si scollega solo il suo nome (percorso) dal suo contenuto (inode). L'inode viene mantenuto in vita finché ci sono processi che lo aprono per la lettura o la scrittura.
Ciò comporta numerosi effetti negativi: i registri scritti dopo l'eliminazione del file vengono persi in quanto non esiste un modo semplice / portatile per aprire un file eliminato. Finché un processo sta scrivendo sul file eliminato, il suo contenuto sta ancora utilizzando lo spazio sul file system. Ciò significa che se si rimuove / crea il file perché stava riempiendo il disco, il disco rimane pieno. Un modo per risolvere quest'ultimo problema è riavviare i processi del logger, ma potresti non voler farlo per i servizi critici e i log degli intermediari andrebbero definitivamente persi. Ci sono anche effetti collaterali a causa del fatto che il file che crei potrebbe non avere gli stessi permessi, proprietario e gruppo di quello originale. Ciò, ad esempio, potrebbe impedire a un analizzatore di log di leggere il file appena creato o, peggio ancora, impedire al processo di registrazione di scrivere i propri log.
Il primo metodo, cat /dev/null > file
raggiungere l'obiettivo correttamente , tuttavia, nonostante una tenace leggenda urbana, la sua cat /dev/null
parte non fa assolutamente nulla di utile. Apre uno pseudo file che è vuoto di progettazione, non riesce a leggere nulla da esso e alla fine esce. L'uso di questo comando è quindi uno spreco di sequenze di tasti, byte, chiamate di sistema e cicli della CPU e può essere sostituito senza alcuna modifica funzionale dal comando no-op indubbiamente più veloce:
o addirittura, con la maggior parte delle shell, da nessun comando.
Vorrei provare una metafora per spiegare quanto sia inutile cat /dev/null
. Diciamo che il tuo obiettivo è quello di svuotare un bicchiere.
Prima rimuovi qualsiasi liquido da esso. Questo è sufficiente ed è esattamente ciò che ( > file
) dato il fatto che i reindirizzamenti vengono sempre elaborati per primi.
Quindi, scegli una bottiglia vuota ( /dev/null
) e la versi nel bicchiere vuoto ( cat
). Questo è il passo inutile ...
Se leggi il documento collegato fino alla fine, potresti notare i commenti in questa riga dalla versione avanzata dello script:
cat / dev / null> wtmp # ':> wtmp' e '> wtmp' hanno lo stesso effetto.
Hanno davvero; troppo male è cat /dev/null
stato mantenuto nel codice.
Ciò significa che il seguente codice funzionerà con tutte le shell comuni (sia csh
e sh
famiglie):
cd /var/log
: > messages
: > wtmp
echo "Log files cleaned up."
e questo lavorerà con tutte le shell utilizzando la sintassi Bourne, come ash
, bash
, ksh
, zsh
e simili:
cd /var/log
> messages
> wtmp
echo "Log files cleaned up."
Si noti tuttavia che con antiche shell Bourne pre-POSIX, uno qualsiasi di questi comandi, incluso cat /dev/null
non troncerà un file se viene scritto successivamente da uno script di shell ancora in esecuzione che lo aggiunge. Invece di un file a zero byte, sarebbe un file sparso con le sue dimensioni invariate. Lo stesso accadrebbe se il file è stato scritto da un processo che cerca la posizione che ritiene sia quella corrente prima di scrivere.
Attenzione anche che alcune soluzioni alternative suggeriscono spesso di troncare un file presentano dei difetti.
Entrambi i seguenti semplicemente non fanno il lavoro. Il file risultante non è vuoto ma contiene una riga vuota. Ciò spezzerebbe i file di registro come quelli wtmp
che archiviano record a larghezza fissa.
echo > file
echo "" > file
Il prossimo basato su sh
un'opzione BSD non è portatile, POSIX non specifica alcuna opzione consentita per l'eco, quindi potresti finire con un file contenente una riga con " -n
":
echo -n > file
Quello non portatile neanche usando una sh
sequenza di fuga di System V. Alcune shell creeranno un file contenente una riga con " \c
":
echo "\c" > file
Quello usa un comando progettato per fare il lavoro. Il problema che sta utilizzando truncate
non è portatile perché questo comando, non specificato da POSIX, potrebbe non essere presente in un sistema Unix / Linux.
truncate -s 0
Infine, ecco un paio di alternative che sono portatili e faranno correttamente il lavoro: