2010-06-16 16 views
29

considerar algo como:¿Está bien utilizar el mismo archivo de entrada como salida de un comando canalizado?

cat file | command > file 

¿Es esta buena práctica? ¿Podría esto sobreescribir el archivo de entrada al mismo tiempo que lo estamos leyendo, o siempre se lee primero en la memoria y luego se canaliza al segundo comando?

Obviamente, puedo usar los archivos temporales como paso intermedio, pero me pregunto ..

t=$(mktemp) 
cat file | command > ${t} && mv ${t} file 

Respuesta

44

No, no está bien. Todos los comandos en una canalización se ejecutan al mismo tiempo, y el shell prepara las redirecciones antes de ejecutar los comandos. Por lo tanto, es probable que el comando sobrescriba el archivo antes de que cat lo lea.

Necesita sponge(1) de moreutils.

+0

gracias, moreutils se ve muy útil! ¿Se aplica lo mismo a la redirección: 'comando < file > file' o incluso a la sustitución de proceso:' comando <(cat file) > file'? – Amro

+2

Sí, también se aplica en ambos casos. Tenga en cuenta que el shell es libre de configurar las redirecciones en cualquier orden, por lo que debe considerar el comportamiento indefinido para acceder al mismo archivo dos veces en un solo comando o canalización. Incluso funciona ocasionalmente, no está garantizado. – Juliano

3

También puede usar algo como esto (no se recomienda, utilizar archivos temporales explícitas en el código de producción):

{ rm file && your_command > file; } < file 
0

No sólo debe NO escriba su salida a su entrada, sino que también se debe evitar bucles de su salida de vuelta a su entrada.

Cuando se trata de archivos grandes, he intentado

cat *allfastq30 > Sample_All_allfastq30 

y genera mensajes de error:

cat: Sample_All_allfastq30: input file is output file 
Cuestiones relacionadas