Me pregunto qué deberíamos usar para canalizar y cuándo no.
Digamos, por ejemplo, que para matar ciertos procesos que manejan archivos pdf, lo siguiente no funcionará usando pipeline:
ps aux | grep pdf | awk '{print $2}'|kill
En cambio, solo podemos hacerlo de las siguientes maneras:
kill $(ps aux| grep pdf| awk '{print $2}')
o
ps aux | grep pdf | awk '{print $2}'| xargs kill
Según man bash(versión 4.1.2):
The standard output of command is connected via a pipe to the standard input of command2.
Para el escenario anterior:
- el stdin de
grepes el stdout deps. Eso funciona. - el stdin de
awkes el stdout degrep. Eso funciona. - el stdin de
killes el stdout deawk. Eso no funciona
El stdin del siguiente comando siempre recibe información del stdout del comando anterior.
- ¿Por qué no funciona con
killorm? - ¿Cuál es la diferencia entre
kill,rmde entrada, congrep,awkde entrada? - ¿Hay alguna regla?

pgrep,pkilly loskillallcomandos.pgrepy el resto puede lograr esto perfectamente :)Respuestas:
Hay dos formas comunes de proporcionar aportes a los programas:
killusa solo argumentos de línea de comando. No lee de STDIN. Los programas tienen gustogrepyawkleen de STDIN (si no se dan nombres de archivo como argumentos de línea de comando) y procesan los datos de acuerdo con sus argumentos de línea de comando (patrón, declaraciones, banderas, ...).Solo puede canalizar a STDIN de otros procesos, no a argumentos de línea de comando.
La regla común es que los programas usan STDIN para procesar una cantidad arbitraria de datos. Todos los parámetros de entrada adicionales o, si generalmente hay solo unos pocos, se pasan por argumentos de línea de comando. Si la línea de comando puede ser muy larga, por ejemplo, para
awktextos de programa largos , a menudo existe la posibilidad de leerlos desde archivos de programa adicionales (-fopción deawk).Para usar el STDOUT de programas como argumentos de línea de comando, use
$(...)o en caso de muchos datosxargs.findTambién puede esto directamente con-exec ... {} +.Para completar: Para escribir argumentos de línea de comando en STDOUT, use
echo.fuente
gzipen la SINOPSIS, no dijo que debe tomar un FILENAME como entrada. Estoy buscando hay una manera más sistemática para determinar eso.xargspermitirá precisamente "canalizar los argumentos de la línea de comando"?xargs. Llama al comando si es necesario más de una vez (el tamaño de la línea de comando es limitado) y tiene muchas otras opciones.Esta es una pregunta interesante, y trata con una parte de la filosofía de Unix / Linux.
Así que, ¿cuál es la diferencia entre programas como
grep,sed,sortpor un lado, ykill,rm,lsen el otro lado? Veo dos aspectos.El aspecto del filtro
El primer tipo de programas también se llama filtros . Toman una entrada, ya sea de un archivo o de STDIN, la modifican y generan alguna salida, principalmente a STDOUT. Están destinados a ser utilizados en una tubería con otros programas como fuentes y destinos.
El segundo tipo de programas actúa sobre una entrada, pero la salida que dan a menudo no está relacionada con la entrada.
killno tiene salida cuando funciona regularmente, tampoco lo hacels. Solo tienen un valor de retorno para mostrar el éxito. Normalmente no reciben información de STDIN, pero en su mayoría dan salida a STDOUT.Para programas como
ls, el aspecto del filtro no funciona tan bien. Ciertamente puede tener una entrada (pero no la necesita), y la salida está estrechamente relacionada con esa entrada, pero no funciona como filtro. Sin embargo, para ese tipo de programas, el otro aspecto aún funciona:El aspecto semántico.
Para los filtros, su entrada no tiene significado semántico . Simplemente leen datos, modifican datos, generan datos. No importa si se trata de una lista de valores numéricos, algunos nombres de archivo o código fuente HTML. El significado de estos datos solo viene dado por el código que usted proporciona al filtro: la expresión regular para
grep, las reglas paraawko el programa Perl.Para otros programas, como
killols, su entrada tiene un significado , una denotación .killespera números de proceso,lsespera nombres de archivo o ruta. No pueden manejar datos arbitrarios y no están destinados a hacerlo. Muchos de ellos ni siquiera necesitan ninguna entrada o parámetro, comops. Normalmente no leen de STDIN.Probablemente se podrían combinar estos dos aspectos: un filtro es un programa cuya entrada no tiene un significado semántico para el programa.
Estoy seguro de que he leído sobre esta filosofía en alguna parte, pero no recuerdo ninguna fuente en este momento, lo siento. Si alguien tiene algunas fuentes presentes, no dude en editar.
fuente
No hay "reglas" como tales. Algunos programas reciben información de STDIN y otros no. Si un programa puede recibir información de STDIN, se puede canalizar a, si no, no puede.
Normalmente puede saber si un programa tomará información o no al pensar en lo que hace. Si el trabajo del programa es manipular de alguna forma los contenidos de un archivo (por ejemplo
grep,sed,awketc.), que normalmente toma de entrada de STDIN. Si su trabajo consiste en manipular el archivo en sí (por ejemplomv,rm,cp) o un proceso (por ejemplokill,lsof) o a la información de retorno sobre algo (por ejemplotop,find,ps), entonces no lo hace.Otra forma de pensarlo es la diferencia entre argumentos y aportes. Por ejemplo:
En el comando anterior,
mvno tiene entrada como tal. Lo que se le ha dado son dos argumentos. No sabe ni le importa lo que hay en ninguno de los archivos, solo sabe que esos son sus argumentos y debe manipularlos.Por otra parte
Aquí,
sedse ha dado información y un argumento. Como toma entrada, puede leerlo desde STDIN y puede canalizarlo.Se vuelve más complicado cuando un argumento puede ser la entrada. Por ejemplo
Aquí
fileestá el argumento que se le diocat. Para ser precisos, el nombre del archivofilees el argumento. Sin embargo, dado quecates un programa que manipula el contenido de los archivos, su entrada es lo que esté dentrofile.Esto puede ilustrarse con
straceun programa que rastrea las llamadas al sistema realizadas por los procesos. Si corremos acat footravés destrace, podemos ver que el archivofooestá abierto:La primera línea de arriba muestra que el programa
/bin/catfue llamado y sus argumentos fueroncatyfoo(el primer argumento es siempre el programa en sí). Más tarde, el argumentofoose abrió en modo de solo lectura. Ahora, compara esto conAquí también, se
lstomó yfoocomo argumentos. Sin embargo, no hayopenllamada, el argumento no se trata como entrada. En cambio,lsllama a lastatbiblioteca del sistema (que no es lo mismo que elstatcomando) para obtener información sobre el archivofoo.En resumen, si el comando que está ejecutando leerá su entrada, puede canalizarlo, si no lo hace, no puede.
fuente
killyrmno necesita STDIN.Para
killyrm, los usuarios proporcionan su información personalizada como argumento, y$(cmd)ayuda a tomar el STDOUT decmdy convertir su argumento de información.Para
grepyawk, los usuarios proporcionan argumentos y, además, tambiénSTDINo un archivo normal que será procesado por el comando.STDINse puede pasar con tubería|o ingresando manualmente.Lea el manual o los códigos fuente. Y si no encuentra nada de lo que necesita, puede hacer una prueba simple pero quizás peligrosa:
Simplemente ingrese el comando que le interesa, con argumentos que ya ha entendido, y vea si el comando se detiene (no pasa nada). Si pausa, en realidad está a la espera de STDIN (puedes probar
catyechover el diferente). Escribe manualmenteCtrl-Dy el comando continúa (muestra resultados o errores) y regresa. Tal comando necesita STDIN en esa situación (con argumentos que proporcione).El mismo comando puede no necesitar STDIN en diferentes situaciones (por ejemplo,
catespera STDIN perocat file.txtno).fuente