Risposte:
cat /dev/null > file.txtè un uso inutile del gatto .
Fondamentalmente cat /dev/nullsi traduce semplicemente in catnon 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.txtfunzionerà 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 trueuscita 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.txtsintassi.
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 trueche è considerato un built-in "speciale" .
>| fileè un troncato più esplicito.
truenon è richiesto per essere incorporato e tradizionalmente no. :è costruito in tutte le conchiglie della famiglia Bourne. :è un builtin speciale per POSIX (quindi : > fileuscirà dalla shell per esempio se filenon può essere aperto per la scrittura nelle shell POSIX) e truenon lo è. POSIX menziona anche che :potrebbe essere più efficiente rispetto truead 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:
sho kshemulazione, per i reindirizzamenti senza un comando, in zsh, viene assunto un comando predefinito (un cercapersone solo per il reindirizzamento stdin, cataltrimenti), 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 evalessendo built-in speciali, se il reindirizzamento fallisce, esce dalla shell (lo bashfa solo in modalità POSIX).(t)cshquesto 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, cpe printfgeneralmente sono (POSIX li richiede)).fileè un collegamento simbolico a un file inesistente, alcune cpimplementazioni 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/nullin file? catviene 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 cpfare per impostazione predefinita potrebbe pensare che stai cercando di creare anche fileun nulldispositivo.eval > fileo 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.
cpe catgeneralmente non sono integrati.
Ora cp /dev/null filenon 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 : > filein 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=0viene ignorato. dd if=/dev/null of=filesarebbe 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.
truncatesarebbe disponibile, ma >né le unistdlibrerie C né sarebbero disponibili?
truncateè un'utilità FreeBSD, relativamente recente (2008) aggiunta ai coreutils GNU (sebbene lo --sizestile 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 filefunzionerebbe 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.txte vuoi ruotarlo.
Pertanto, ad esempio, si copia file.txtin file.txt.save, quindi si tronca file.txt.
In questo scenario, SE il file non viene aperto da another_process(es: another_processpotrebbe 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_processelemento è ancora attivo e ha ancora un handle aperto che va al file.txt.
Quindi, sorgono 2 casi principali, a seconda di come è stato other processaperto il file:
Se lo other_processapre 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_processaperto file.txtin "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_processche stanno ancora scrivendo in quella posizione lo abbiano aperto in modalità "Aggiungi". Altrimenti dovrai interromperli other_processe 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 > filee a > fileè a cat /dev/nulle 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?
echoimplementazioni non supportano -n(e verrebbero emesse -n<SPC><NL>qui. printf '' > file.txtSarebbero più portatili (almeno attraverso i sistemi moderni / POSIX).