2010-03-31 18 views
13

¿Hay un caso de ... o contexto donde cat file | ... se comporta de manera diferente a ... <file?cat archivo | ... vs ... <archivo

+0

Si está preguntando por qué ve una u otra forma utilizada en diferentes lugares, parece ser una cuestión de preferencia personal. Kernighan y Pike lo notaron en 1984: http://www.amazon.com/Unix-Programming-Environment-Prentice-Hall-Software/dp/013937681X – msw

+1

Pertenece a superuser.com –

Respuesta

9

Al leer de un archivo normal, cat es el encargado de leer los datos, realizarlos como lo desee y restringirlos en la forma en que lo escribe en la canalización. Obviamente, los contenidos mismos se conservan, pero cualquier otra cosa podría estar contaminada. Por ejemplo: tamaño de bloque y tiempo de llegada de datos. Además, el tubo en sí mismo no siempre es neutral: sirve como un búfer adicional entre la entrada y ....

manera rápida y fácil de hacer la edición del tamaño de bloque aparente:

$ cat large-file | pv >/dev/null 
5,44GB 0:00:14 [ 393MB/s] [    <=>         ] 
$ pv <large-file >/dev/null 
5,44GB 0:00:03 [1,72GB/s] [=================================>] 100% 
+1

Interesante, aunque dado que read() usa un búfer finito, de cualquier forma, alcanzará el tamaño mínimo de búfer en algunos procesos. strace muestra que cat usa lecturas de 32kB y pv 128kB en mi plataforma. – msw

+0

Oh, hey, mi ejemplo no coincide con la pregunta, ya que no estoy usando

+0

@msw dependerá * muy * de la implementación de 'cat', pero trataré de hacerlo aparente de otra manera. –

1

cat file | inicia otro programa (cat) que no tiene que comenzar en el segundo caso. También lo hace más confuso si desea usar "aquí documentos". Pero debería comportarse igual.

4

cat le permitirá conectar varios archivos secuencialmente. De lo contrario, la redirección < y cat file | producen los mismos efectos secundarios.

2

Tubos causan una subcapa a ser invocada para el comando a la derecha. Esto interfiere con las variables de entorno.

cat foo | while read line 
do 
    ... 
done 
echo "$line" 

frente

while read line 
do 
    ... 
done < foo 
echo "$line" 
+0

Ambos dieron los mismos resultados cuando los probé. –

+0

interesante efecto secundario. – pra

+0

@JB: establece una variable dentro del bucle, luego haz eco después del bucle. El valor modificado solo persistirá después del formulario redirigido y no lo hará después de la forma intercalada. Otra demostración es 'cd' dentro del loop y' pwd' después del loop. –

4

Además de lo publicado por otros usuarios, al utilizar la redirección de entrada de un archivo, la entrada estándar es el archivo pero cuando tubería de la salida de gato a la entrada, la entrada estándar es una secuencia con el contenido del archivo. Cuando la entrada estándar es el archivo podrá buscar dentro del archivo, pero la tubería no lo permitirá. Esto se puede ver mediante la búsqueda de un archivo zip y ejecutando los siguientes comandos:

zipinfo /dev/stdin < thezipfile.zip 

y

cat thezipfile.zip | zipinfo /dev/stdin 

El primer comando mostrará el contenido del archivo zip mientras que el segundo se mostrará un error, aunque es un error engañoso porque zipinfo no verifica el resultado de la llamada de búsqueda y los errores más adelante.

3

A uso inútil de gato es siempre debe evitarse. Es como conducir con el freno de mano en. Desperdicia ciclos de CPU para nada, el sistema operativo cambia de contexto constantemente entre el proceso cat y el siguiente en la tubería. Si todos los gatos inútiles del mundo se hubieran ido y hubieran dejado de inventarse, reinventarse, pasar de padres a hijos, no tendríamos el calentamiento global porque podríamos vivir fácilmente con 1.21 Gigawatts de energía ahorrada.

Gracias. Me siento mejor ahora. Por favor, únase a mí en mi cruzada para acabar con el uso inútil de cat en stackoverflow. Este sitio es, por lo que yo lo percibo, una gran contribución a la proliferación de gatos inútiles. No culpo a los novatos, pero sí quiero enseñarles. ¡Trabajadores y novatos del mundo, afloje los frenos de mano y salve el planeta! 1!

1

Una diferencia más es el comportamiento en un bloqueo open() del archivo de entrada.

Por ejemplo, en el supuesto de entrada es una FIFO sin escritores, una invocación no se generan los programas infantiles hasta que se abra el archivo de entrada, mientras que el otro se generan dos procesos:

prog ... < a_fifo  # 'prog' not launched until shell can open file 
cat a_fifo | prog ... # 'prog' and 'cat' are running (latter may block on open) 

En la práctica esto rara vez importa excepto en circunstancias artificiales. prog puede registrar periódicamente o hacer algún trabajo de limpieza mientras espera la entrada, por ejemplo, que es posible que desee que suceda, incluso si no hay entradas disponibles. (¿Por qué no podría ser prog lo suficientemente sofisticado como para abrir su propia entrada fifo nonblocking?)

Cuestiones relacionadas