2010-10-08 13 views
16

Cuando la salida de un comando se redirige a un archivo, el shell crea o trunca el archivo de salida antes de que se ejecute el comando, ¿hay alguna idea de qué gato foo> foo hace?En UNIX, ¿qué "cat file1> file1 hace?"

+1

Sospecho que esta sería una muy buena prueba del comportamiento del caparazón. –

Respuesta

17

En todos los casos, el archivo se trunca. Esto se debe a que el shell dirige la redirección y abre el archivo para escribir antes de invocar el comando.

cat foo > foo 

Las formas truncadas de concha y abre foo para escribir, establece la salida estándar al archivo, y luego ejecutivo de ["cat", "foo"].

GNU cat es inteligente y se niega a redirigir un archivo a sí mismo. Lo hace comprobando el par dispositivo/inode en los descriptores de archivos de entrada y salida; Puede leer los maravillosos detalles de bajo nivel en src/cat.c. Imprime un mensaje y se cierra.

BSD cat no tiene esa seguridad, pero como el archivo ya se ha truncado, no hay nada que leer, nada que escribir, y se detendrá.


Puede poner un poco de sabor a las cosas agregando en lugar de truncar.

echo hello > foo 
cat foo >> foo 

Ahora todo es lo mismo, excepto la cáscara se abre el archivo para anexar en lugar de truncar la misma.

GNU cat ve lo que hace y se detiene; el archivo no ha sido tocado

BSD cat entra en un bucle y agrega el archivo a sí mismo hasta que se llena el disco.

+0

Y es por eso que Mac está basado en BSD. –

2

El archivo se trunca primero y luego se lee, por lo que este comando truncará el archivo.

Cuando traté de ejecutarlo Tengo esta advertencia:

gato: test.txt: archivo de entrada es el archivo de salida

+0

¿Qué 'gato' de plataforma tienes? 'cat foo> foo' da como resultado un archivo' foo' vacío para mí. – birryree

4

En Fedora 13 esto es lo que veo

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

Si foo contenía algo anteriormente, se va.

1

Shell truncará, cat parecer comprueba un llamado Parm, pero no comprobará contra stdin que a continuación y siempre tiene éxito:

$ 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

Gracias por todas sus respuestas. fueron muy útiles. – HelloWorld