Risposte:
cat /dev/null > file.txt
è un uso inutile del gatto .
Fondamentalmente cat /dev/null
si traduce semplicemente in cat
non produrre nulla. Sì, funziona, ma è disapprovato da molti perché provoca l'invocazione di un processo esterno che non è necessario.
È una di quelle cose che è comune semplicemente perché è comune.
L'uso di Just > file.txt
funzionerà sulla maggior parte delle shell, ma non è completamente portatile. Se vuoi essere completamente portatile, le seguenti sono buone alternative:
true > file.txt
: > file.txt
Sia :
e true
uscita dati, e sono intrinseche della shell (che cat
è un programma di utilità esterno), quindi sono più leggeri e più 'corretta'.
Aggiornare:
Come ha detto Tylerl nel suo commento, c'è anche la >| file.txt
sintassi.
La maggior parte delle shell ha un'impostazione che impedisce loro di troncare un file esistente tramite >
. È necessario utilizzare >|
invece. Questo serve a prevenire l'errore umano quando intendevi davvero accontentarti >>
. È possibile attivare il comportamento con set -C
.
Quindi, con questo, penso che il metodo più semplice, più appropriato e portatile per troncare un file sarebbe:
:>| file.txt
:
anche il mandato di POSIX per essere integrato, e in effetti è diverso dal fatto true
che è considerato un built-in "speciale" .
>| file
è un troncato più esplicito.
true
non è richiesto per essere incorporato e tradizionalmente no. :
è costruito in tutte le conchiglie della famiglia Bourne. :
è un builtin speciale per POSIX (quindi : > file
uscirà dalla shell per esempio se file
non può essere aperto per la scrittura nelle shell POSIX) e true
non lo è. POSIX menziona anche che :
potrebbe essere più efficiente rispetto true
ad alcuni sistemi.
Bourne POSIX zsh csh/tcsh rc/es fish
> file Y Y N(1) N(1) N N
: > file N/Y(2) Y(3) Y Y(4) N(5) N(5)
true > file Y(5) Y Y Y(5) Y(5) Y(5)
cat /dev/null > file Y(5) Y Y(5) Y(5) Y(5) Y(5)
eval > file Y(3,8) Y(3) Y Y(6) Y Y
cp /dev/null file (7) Y(5) Y Y(5) Y(5) Y(5) Y(5)
printf '' > file Y(5) Y Y Y(5) Y(5) Y
Gli appunti:
sh
o ksh
emulazione, per i reindirizzamenti senza un comando, in zsh, viene assunto un comando predefinito (un cercapersone solo per il reindirizzamento stdin, cat
altrimenti), che può essere regolato con le variabili NULLCMD e READNULLCMD. Questo si ispira alla funzionalità simile in(t)csh
:
in UnixV7 poiché :
venivano interpretati a metà strada tra un commentatore e un comando null. Successivamente sono stati e come per tutti i builtin, se il reindirizzamento fallisce, questo esce dalla shell.:
ed eval
essendo built-in speciali, se il reindirizzamento fallisce, esce dalla shell (lo bash
fa solo in modalità POSIX).(t)csh
questo sta definendo un'etichetta null (per goto
), quindi goto ''
lì si ramificherebbe. Se il reindirizzamento non riesce, si esce dalla shell.$PATH
( :
generalmente non è, true
, cat
, cp
e printf
generalmente sono (POSIX li richiede)).file
è un collegamento simbolico a un file inesistente, alcune cp
implementazioni come GNU si rifiuteranno di crearlo.(questa sezione è altamente soggettiva)
> file
. Che >
sembra troppo simile una richiesta o un commento. Inoltre, la domanda che farò quando la leggerò (e la maggior parte delle shell si lamenterà dello stesso) è quale output stai esattamente reindirizzando? .: > file
. :
è noto come il comando no-op. In questo modo si legge subito come generare un file vuoto. Tuttavia, anche in questo caso, :
può essere facilmente perso e / o visto come un prompt.true > file
: cosa c'entra il booleano con il reindirizzamento o il contenuto del file? Cosa si intende qui? è la prima cosa che mi viene in mente quando l'ho letto.cat /dev/null > file
. Concatenare /dev/null
in file
? cat
viene spesso visto come il comando per scaricare il contenuto del file, che può ancora dare un senso: il dump del contenuto del il file vuoto infile
, un po 'come un modo contorto per dire cp /dev/null file
, ma ancora comprensibile.cp /dev/null file
. Copia il contenuto del file vuoto in file
. Ha senso, anche se qualcuno che non sa come cp
fare per impostazione predefinita potrebbe pensare che stai cercando di creare anche file
un null
dispositivo.eval > file
o eval '' > file
. Non esegue nulla e reindirizza il suo output a file
. Ha senso per me. Strano che non sia un linguaggio comune.printf '' > file
: non stampa esplicitamente nulla in un file. Quello che ha più senso per me.La differenza sarà se stiamo usando una shell integrata o no. In caso contrario, è necessario eseguire un fork di un processo, il comando deve essere caricato ed eseguito.
eval
è garantito per essere costruito in tutte le shell. :
è integrato ovunque sia disponibile (Mi piace Bourne / csh). true
è incorporato solo in shell tipo Bourne.
printf
è la maggior parte delle conchiglie Bourne e fish
.
cp
e cat
generalmente non sono integrati.
Ora cp /dev/null file
non invoca reindirizzamenti della shell, quindi cose come:
find . -exec cp /dev/null {} \;
saranno più efficienti di:
find . -exec sh -c '> "$1"' sh {} \;
(anche se non necessariamente di:
find . -exec sh -c 'for f do : > "$f"; done' sh {} +
).
Personalmente, uso : > file
in shell tipo Bourne e al giorno d'oggi non uso altro che shell tipo Bourne.
dd of=file count=0
?
dd
(come almeno Solaris 10), count=0
viene ignorato. dd if=/dev/null of=file
sarebbe più portatile. In ogni caso, è indipendente dalla shell.
cp /dev/null file
, giusto?
cp /dev/null file
è un linguaggio comune. Sto limitando a quelli, il punto non è elencare tutti i modi possibili.
Potresti voler guardare truncate
, il che fa esattamente questo: troncare un file.
Per esempio:
truncate --size 0 file.txt
Questo è probabilmente più lento dell'uso true > file.txt
.
Il mio punto principale tuttavia è: truncate
è destinato al troncamento dei file, mentre l'utilizzo di> ha l'effetto collaterale di troncare un file.
truncate
sarebbe disponibile, ma >
né le unistd
librerie C né sarebbero disponibili?
truncate
è un'utilità FreeBSD, relativamente recente (2008) aggiunta ai coreutils GNU (sebbene lo --size
stile di opzione lunga GNU sia specifico GNU), quindi non è disponibile nei sistemi non GNU-o-FreeBSD e non è disponibile nei sistemi GNU precedenti, Non direi che sia portatile. cp /dev/null file
funzionerebbe senza un reindirizzamento della shell e sarebbe più portatile.
La risposta dipende un po 'da ciò che file.txt
è e da come il processo ci scrive!
Citerò un caso d'uso comune: hai un file di registro in crescita chiamato file.txt
e vuoi ruotarlo.
Pertanto, ad esempio, si copia file.txt
in file.txt.save
, quindi si tronca file.txt
.
In questo scenario, SE il file non viene aperto da another_process
(es: another_process
potrebbe essere un programma in uscita su quel file, ad esempio un programma che registra qualcosa), quindi le tue 2 proposte sono equivalenti ed entrambe funzionano bene (ma la seconda è preferita come prima "cat / dev / null> file.txt" è un uso inutile di Cat e apre e legge anche / dev / null).
Ma il vero problema sarebbe se l' other_process
elemento è ancora attivo e ha ancora un handle aperto che va al file.txt.
Quindi, sorgono 2 casi principali, a seconda di come è stato other process
aperto il file:
Se lo other_process
apre in modo normale, l'handle indicherà comunque la posizione precedente nel file, ad esempio con offset 1200 byte. La prossima scrittura inizierà quindi all'offset 1200, e quindi avrai di nuovo un file di 1200bytes (+ qualunque cosa abbia scritto altro_processo), con 1200 caratteri null iniziali! Non è quello che vuoi , presumo.
Se other_process
aperto file.txt
in "modalità append", ogni volta che scrive, il puntatore cercherà attivamente fino alla fine del file. Pertanto, quando lo tronchi, "cercherà" fino al byte 0 e non avrai l'effetto collaterale negativo! Questo è quello che vuoi (... di solito!)
Si noti che ciò significa che, quando si tronca un file, è necessario assicurarsi che tutti quelli other_process
che stanno ancora scrivendo in quella posizione lo abbiano aperto in modalità "Aggiungi". Altrimenti dovrai interromperli other_process
e riavviarli, in modo che inizino a puntare all'inizio del file anziché nella posizione precedente.
Riferimenti: /programming//a/16720582/1841533 per una spiegazione più chiara e un breve esempio di differenza tra registrazione in modalità normale e aggiunta su /programming//a/984761/1841533
cat /dev/null > file
e a > file
è a cat /dev/null
e non fa alcuna differenza per il file.
Mi piace e lo uso spesso perché sembra più pulito e non come se qualcuno avesse premuto il tasto Invio per errore:
echo -n "" > file.txt
Dovrebbe essere anche un built-in?
echo
implementazioni non supportano -n
(e verrebbero emesse -n<SPC><NL>
qui. printf '' > file.txt
Sarebbero più portatili (almeno attraverso i sistemi moderni / POSIX).