redirección de gato

11

Digamos que un archivo llamado abcexiste en el directorio actual y tiene texto. Cuando ejecutas el comando:

cat abc > abc

¿Por qué abcdesaparece el contenido del archivo ?
¿Por qué el comando elimina el texto que contiene y el archivo se convierte en un archivo vacío?

Tulsi Kanodia
fuente
Y para obtener soluciones, consulte ¿Puedo hacer cutcambiar un archivo en su lugar?
Gilles 'SO- deja de ser malvado'
10
Un puntero láser es una herramienta muy efectiva para la redirección de gatos. </pun>
WBT
Mi gato responde muy mal a la redirección ...
Ex Umbris
Para evitar este problema, utilizo un pequeño shellscript que llamé perro :cat abc | dog abc
joeytwiddle
Otra opción, si no le importa el resultado en pantalla, es usar tee.
Andrea Lazzarotto

Respuestas:

27

Por el orden en que se hacen las cosas.

Cuando tu lo hagas:

cat abc > abc

>es el operador de redireccionamiento de salida, cuando el shell ve esto, abre el archivo en modo de truncamiento usando la O_TRUNCmarca con open(2)ie open("abc", O_TRUNC), por lo que todo lo que había en el archivo desaparecerá. Tenga en cuenta que esta redirección se realiza primero por el shell antes de que se catejecute el comando.

Entonces, cuando se cat abcejecuta el comando , el archivo abcya está truncado, por catlo tanto , encontrará el archivo vacío.

heemayl
fuente
1
¿Qué pasa con cat abc >> abc? ¿Qué pasa entonces?
Tulsi Kanodia
2
@TulsiKanodia: eso provoca un bucle infinito. Cada vez que el gato lee una línea, agrega otra antes de pasar a la siguiente.
user3490
3
Esto se detecta y se previene. En cambio, el texto cat: filename: input file is output file(donde filenameestá el nombre de archivo que eligió) se imprime en el stdout antiguo.
UTF-8
@TulsiKanodia Ver unix.stackexchange.com/questions/154903/why-does-cat-xx-loop
Gilles 'SO- deja de ser malvado'
5

Agregando a la respuesta de @ heemayl , si desea que el código sea más claro acerca de la secuencia en la que están sucediendo las cosas, simplemente puede colocar las redirecciones al comienzo del comando:

> abc cat abc
l0b0
fuente