2010-09-16 13:40:08 +0000 2010-09-16 13:40:08 +0000
88
88

¿Cómo canalizar la salida de un comando a otros comandos?

Ejemplo:

ls | echo no imprime nada ( una línea en blanco, en realidad ). Yo esperaría que imprimiera una lista de archivos.

ls | grep 'foo', por otro lado, funciona como se espera ( imprime archivos con ‘foo’ en su nombre ).

Lo que hago en estas situaciones es algo así: ls | while read OUT; do echo $OUT; done pero esto es bastante engorroso.

¿Por qué el piping funciona con algunos comandos, pero no con otros? ¿Cómo puedo evitar este problema?

Respuestas (4)

123
123
123
2010-09-16 14:16:59 +0000

Existe una distinción entre los argumentos de la línea de comandos y la entrada estándar. Una tubería conectará la salida estándar de un proceso con la entrada estándar de otro. Así que

ls | echo

Conecta la salida estándar de ls con la entrada estándar de echo. ¿Está bien, verdad? Pues bien, echo ignora la entrada estándar y volcará sus argumentos de línea de comandos -que no son ninguno en este caso- a su propia salida estándar. La salida: nada en absoluto.

Hay algunas soluciones en este caso. Una es utilizar un comando que lea stdin y vuelque a stdout, como cat.

ls | cat

“Funcionará”, dependiendo de cuál sea su definición de trabajo.

Pero qué pasa con el caso general. Lo que realmente quieres es convertir la salida estándar de un comando en los argumentos de la línea de comandos de otro. Como otros han dicho, xargs es la herramienta de ayuda canónica en este caso, leyendo sus argumentos de línea de comandos para un comando desde su stdin, y construyendo comandos para ejecutar.

ls | xargs echo

También podrías convertir esto en algo, usando el comando de sustitución $()

echo $(ls)

También haría lo que quieres.

Ambas herramientas son muy importantes para el shell scripting, deberías aprender ambas.

Para completar, como indicas en la pregunta, la otra forma básica de convertir stdin en argumentos de línea de comandos es el comando read incorporado en el shell. Convierte las “palabras” (palabras definidas por la variable IFS) en una variable temporal, que puedes utilizar en cualquier ejecución de comandos.

19
19
19
2010-09-16 13:54:37 +0000

ls | echo imprime sólo una línea en blanco porque echo no lee ninguna entrada; el último comando de la tubería es en realidad echo que no imprime nada más que una línea en blanco.

Generalmente:

a | b

se asegura de que la salida de a se convierta en la entrada de b. Te sugiero que leas la sección Pipelines de man bash.

  • *

Si realmente quieres usar ls y echo juntos aquí tienes algunos ejemplos (bastante inútiles):

ls | xargs -L 1 echo
echo `ls`
for i in `ls` ; do echo $i ; done
13
13
13
2010-09-16 14:03:04 +0000

Si quieres echo el comando ls prueba:

ls | xargs echo

Esto llamará a echo con la salida de ls.

3
3
3
2011-11-09 09:48:27 +0000

¿Por qué no utilizar simplemente:

echo `ls`

O mucho más seguro:

echo "`ls -lrt`"