Stavo cercando di modificare rapidamente un .hgignore
file dalla shell bash di Cygwin oggi e ho aggiunto una riga che era un errore. Non sono sicuro che questo fosse il modo migliore per farlo, ma ho subito pensato di usare head -1 .hgignore
per rimuovere la riga incriminata (in precedenza avevo avuto solo una riga nel file). Abbastanza sicuro, quando eseguito fornisce la prima riga come unico output.
Ma quando ho provato a reindirizzare l'output e riscrivere il file usando head -1 .hgignore > .hgignore
, il file era vuoto. Perché questo accade? Se invece provo ad aggiungere, head -1 .hgignore >> .hgignore
, si aggiunge correttamente ma questo ovviamente non è il risultato desiderato. Perché un reindirizzamento di troncamento non funziona in questo caso?
Risposta accettata:
Quando la shell riceve una riga di comando come:command > file.out
la shell stessa apre (e forse crea) il file chiamato file.out
. La shell imposta il descrittore di file 0 sul descrittore di file di file ottenuto dall'apertura. Ecco come funziona il reindirizzamento I/O:ogni processo conosce i descrittori di file 0, 1 e 2.
La parte difficile di questo è come per aprire file.out
. La maggior parte delle volte, vuoi file.out
aperto per la scrittura all'offset 0 (cioè troncato) e questo è ciò che la shell ha fatto per te. Ha troncato .hgignore, lo ha aperto per la scrittura, ha duplicato il descrittore di file su 0, quindi ha eseguito head
. File clobbering istantaneo.
In bash shell, esegui un set noclobber
per modificare questo comportamento.