2010-10-08 16 views
16

Quando l'output di un comando viene reindirizzato su un file, il file di output viene creato o troncato dalla shell prima dell'esecuzione del comando, qualsiasi idea di cosa faccia cat foo> foo?In UNIX cosa fa "cat file1> file1?"

+1

Sospetto che questo sarebbe un ottimo test del comportamento della shell. –

risposta

17

In tutti i casi, il file viene troncato. Questo perché il reindirizzamento è gestito dalla shell, che apre il file per la scrittura prima di richiamare il comando.

cat foo > foo 

I tronca shell e apre foo per la scrittura, imposta stdout al file, e poi exec di ["cat", "foo"].

GNU cat è intelligente e rifiuta di reindirizzare un file a se stesso. Lo fa controllando la coppia dispositivo/inode sui descrittori dei file di input e di output; puoi leggere i meravigliosi dettagli di basso livello in src/cat.c. Stampa un messaggio e si chiude.

BSD cat non ha una tale sicurezza, ma poiché il file è già stato troncato, non c'è nulla da leggere, niente da scrivere e si fermerà.


È possibile rendere un po 'le cose un po' aggiungendo anziché troncare.

echo hello > foo 
cat foo >> foo 

Ora tutto è lo stesso eccetto che la shell apre il file per accodarlo invece di troncarlo.

GNU cat vede quello che stai facendo e si ferma; il file è intatto.

BSD cat entra in un loop e aggiunge il file a se stesso fino a riempire il disco.

+0

Ed è per questo che Mac è basato su BSD. –

2

Il file viene troncato prima e quindi letto, quindi questo comando troncherà il file.

Quando ho provato a eseguirlo ho ottenuto questo avvertimento:

gatto: test.txt: file di input è file output

+0

Quale 'cat' della piattaforma hai? 'cat foo> foo' produce per me un file' foo' vuoto. – birryree

4

su Fedora 13 questo è quello che vedo

cat foo > foo 
cat: foo: input file is output file 

Se foo contiene qualcosa precedentemente, non c'è più.

1

Shell troncherà, cat controlla apparentemente un parm di nome, ma non controlla contro stdin come qui sotto e sempre riesce:

$ uname -a 
Linux bar 2.6.18-164.15.1.el5PAE #1 SMP Wed Mar 17 12:14:29 EDT 2010 i686 i686 i386 GNU/Linux 
$ dd if=/dev/urandom of=foo bs=1024 count=4 
4+0 records in 
4+0 records out 
4096 bytes (4.1 kB) copied, 0.00334456 seconds, 1.2 MB/s 
$ od -c foo |head -2 
0000000 U 371 003 z 224 334 z K 236 221 k  < c 256 ! 
0000020 % % 256 V \ 005 , 254 X 202 330 004 222 " 037 226 
$ cat <foo >foo && od -c foo 
0000000 
+0

Grazie per tutte le vostre risposte. erano tutti utili. – HelloWorld