¿Cuál es un buen ejemplo de comandos de tuberías juntos?


33

Si estuviera ayudando a alguien a aprender el concepto de tuberías en la línea de comando, ¿qué ejemplo usaría? El ejemplo que realmente surgió fue el siguiente:

cat whatever.txt | less

Siento que ese no es el mejor ejemplo, es decir, porque solo hay un paso. ¿Qué es un uso bueno, pero fundamental |?

Idealmente, el ejemplo que presentaré utilizará programas que tengan salidas propias que se puedan ejecutar de forma independiente y luego se muestren juntos.


3
Su ejemplo realmente no es tan bueno, es básicamente una nominación para el premio de uso inútil del gato.
maxschlepzig

@maxschlepzig No es que nos equivoquemos, pero tampoco eres muy útil; no es necesario catpara eso, ya que less whatever.txtfunciona bien.
Bora M. Alper

Respuestas:


34

Voy a guiarte a través de un ejemplo algo complejo, basado en un escenario de la vida real.

Problema

Digamos que el comando conkydejó de responder en mi escritorio y quiero eliminarlo manualmente. Sé un poco de Unix, así que sé que lo que tengo que hacer es ejecutar el comando kill <PID>. Con el fin de recuperar el PID, puedo usar pso topo cualquier herramienta de distribución de Unix mi me ha dado. Pero, ¿cómo puedo hacer esto en un solo comando?

Responder

$ ps aux | grep conky | grep -v grep | awk '{print $2}' | xargs kill

DESCARGO DE RESPONSABILIDAD: Este comando solo funciona en ciertos casos. No lo copie / pegue en su terminal y comience a usarlo, podría matar procesos desprevenidos. Más bien aprende a construirlo .

Cómo funciona

1- ps aux

Este comando generará la lista de procesos en ejecución y alguna información sobre ellos. La información interesante es que generará el PID de cada proceso en su segunda columna. Aquí hay un extracto de la salida del comando en mi caja:

$ ps aux
 rahmu     1925  0.0  0.1 129328  6112 ?        S    11:55   0:06 tint2
 rahmu     1931  0.0  0.3 154992 12108 ?        S    11:55   0:00 volumeicon
 rahmu     1933  0.1  0.2 134716  9460 ?        S    11:55   0:24 parcellite
 rahmu     1940  0.0  0.0  30416  3008 ?        S    11:55   0:10 xcompmgr -cC -t-5 -l-5 -r4.2 -o.55 -D6
 rahmu     1941  0.0  0.2 160336  8928 ?        Ss   11:55   0:00 xfce4-power-manager
 rahmu     1943  0.0  0.0  32792  1964 ?        S    11:55   0:00 /usr/lib/xfconf/xfconfd
 rahmu     1945  0.0  0.0  17584  1292 ?        S    11:55   0:00 /usr/lib/gamin/gam_server
 rahmu     1946  0.0  0.5 203016 19552 ?        S    11:55   0:00 python /usr/bin/system-config-printer-applet
 rahmu     1947  0.0  0.3 171840 12872 ?        S    11:55   0:00 nm-applet --sm-disable
 rahmu     1948  0.2  0.0 276000  3564 ?        Sl   11:55   0:38 conky -q

2- grep conky

Solo estoy interesado en un proceso, por lo que utilizo greppara encontrar la entrada correspondiente a mi programa conky.

$ ps aux | grep conky
 rahmu     1948  0.2  0.0 276000  3564 ?        Sl   11:55   0:39 conky -q
 rahmu     3233  0.0  0.0   7592   840 pts/1    S+   16:55   0:00 grep conky

3- grep -v grep

Como puede ver en el paso 2, el comando muestra psel grep conkyproceso en su lista (después de todo, es un proceso en ejecución). Para filtrarlo, puedo ejecutarlo grep -v grep. La opción -vle dice grepque haga coincidir todas las líneas, excepto las que contienen el patrón.

$ ps aux | grep conky | grep -v grep
 rahmu     1948  0.2  0.0 276000  3564 ?        Sl   11:55   0:39 conky -q

NB: Me encantaría saber cómo hacer los pasos 2 y 3 en una sola grepllamada.

4- awk '{print $2}'

Ahora que he aislado mi proceso objetivo. Quiero recuperar su PID. En otras palabras, quiero recuperar la segunda palabra de la salida. Por suerte para mí, la mayoría de los (¿todos?) Unices modernos proporcionarán alguna versión de awkun lenguaje de script que hace maravillas con los datos tabulares. Nuestra tarea se vuelve tan fácil como print $2.

$ ps aux | grep conky | grep -v grep | awk '{print $2}'
 1948

5- xargs kill

Tengo el PID Todo lo que necesito es pasárselo kill. Para hacer esto, lo usaré xargs.

xargs killleerá desde la entrada (en nuestro caso desde la tubería), formará un comando que consta de kill <items>( <items>son lo que lea de la entrada) y luego ejecutará el comando creado. En nuestro caso se ejecutará kill 1948. Misión cumplida.

Ultimas palabras

Tenga en cuenta que, dependiendo de la versión de Unix que esté utilizando, ciertos programas pueden comportarse de manera un poco diferente (por ejemplo, pspueden generar el PID en la columna $ 3). Si algo parece incorrecto o diferente, lea la documentación de su proveedor (o mejor, las manpáginas). También tenga cuidado ya que las tuberías largas pueden ser peligrosas. No haga suposiciones, especialmente cuando use comandos como killo rm. Por ejemplo, si hubo otro usuario llamado 'conky' (o 'Aconkyous'), mi comando también puede matar todos sus procesos en ejecución.

Lo que digo es tener cuidado, especialmente para tuberías largas. Siempre es mejor construirlo interactivamente como lo hicimos aquí, que hacer suposiciones y sentir lástima más tarde.


NB: Me encantaría saber cómo hacer los pasos 2 y 3 en una sola llamada grep. -> grep "conky -q" :)
Wolfy

3
En realidad, ese es un mal ejemplo, como podrías simplemente hacerkill $(pgrep conky)
Patrick

55
Sé que esto es tarde, pero podría simplificarlo aún más parapkill conky
estrugee

2
"" "NB: me encantaría saber una forma de hacer los pasos 2 y 3 en una sola llamada grep". "" En lugar de "aux", use "-o pid, com". -obediente. De esa forma, el proceso grep aparecerá como "grep" en lugar de "grep conky" para que no coincida.
Random832

2
NB: Me encantaría saber cómo hacer los pasos 2 y 3 en una sola grepllamada. grep [c]onkyes lo que estás buscando
AlexT

15

Mi favorito es este:

youtube-dl $1 -q -o - | ffmpeg -i - $2

descarga un video de la url de youtube dada pasada $1y lo muestra como el archivo dado por $2. Observe cómo el archivo se envía silenciosamente -qa STDOUT -o -, se canaliza a ffmpeg y se usa como entrada allí -i -.

Especialmente para los novatos de Linux, este podría ser un ejemplo práctico de por qué la línea de comando puede ser útil y hacer las cosas más fáciles que usar herramientas GUI. No estoy seguro de cuánto tiempo tomaría descargar un video de YouTube y convertir su sonido a mp3. La línea anterior puede hacer eso en unos segundos.


3
youtube-dl tiene una opción para guardar solo audio. Mi mando habitual es la siguiente, donde URL vienen en la entrada estándar: youtube-dl --extract-audio --audio-format mp3 -a -. Sigue siendo un buen ejemplo, pero hay formas más fáciles de hacerlo. (Llama a ffmpeg internamente.)
Brigante

3
@FakeRainBrigand: Jaja, ¡es bueno saberlo! Pero obtuve una alternativa que no debería integrarse: youtube-dl $1 -q -o - | mplayer -reproduce directamente el video dentro de mplayer. Uso ese comando de mi computadora portátil para decirle a mi servidor (que está conectado al televisor) que reproduzca videos. Tengo que agregar -display :0.0 -geometry 400x300+1200+200para que la ventana de mplayer aparezca en la pantalla correcta.
Baarn

9

El uso general (léase: la forma en que lo uso la mayoría de las veces) es cuando, por alguna razón, tengo que ejecutar algunos datos a través de varias herramientas para llevar a cabo diferentes tareas de procesamiento.

Entonces, diría que el uso de tuberías es como pegamento para ensamblar varios bloques de construcción (las diferentes herramientas de UNIX). Como dijo Ulrich, sorty uniqes una estrofa común.

Dependiendo de la audiencia, si desea resaltar este uso de tuberías, podría, por ejemplo, comenzar con: "hey, este programa tiene enlaces a varios PDF interesantes con documentos y notas de clase, pero algunos de ellos se repiten. ¿Puedo? de alguna manera automatizar esto? "

Luego, podría mostrar cómo se lynx --dump --listonlyobtiene la lista de enlaces, cómo greppodría filtrar los enlaces que terminan en .pdf, cómo colrmo sedpodría deshacerse de las lynxescrituras de números que quedan en cada URL, cómo sorty uniqpodría deshacerse de los duplicados, y finalmente cómo wget -i -puede usarse para recuperar el archivos (solía --waitser amable en el servidor, por supuesto).

Me temo que este es un ejemplo complejo. Por otro lado, puede ser útil mostrar el poder de las tuberías cuando solo las conecta y hace que la carcasa lo ejecute todo a la vez.


2
También puede usar sort -uen GNU coreutils .
Teresa e Junior

2

No sé exactamente sobre el bien, pero la canalización grepdebe ser uno de los usos más comunes, posiblemente seguido por wc -l. (Sí, greptiene el -cinterruptor poco conocido ).

Otra estrofa común es | sort | uniq, aunque solo sea porque uniqrequiere que se ordene su entrada.


¡La mayoría de la gente prefiere ... | sort -usi está disponible!

2

No es que lo necesite para este ejemplo, pero:

$ ps aux | grep -v grep | grep conky

... invertir el orden de los greps conserva la coloración, pero es MUCHO menos eficiente. presumiblemente en listas grandes, el color no importaría.

Además, esta página web sugiere:

https://stackoverflow.com/questions/9375711/more-elegant-ps-aux-grep-v-grep

> Johnsyweb respondió el 21 de febrero de 12 a las 10:31
> El truco habitual es este:
> ps aux | grep '[t] erminal'
> ¡Esto coincidirá con las líneas que contienen terminal, que grep '[t] erminal' no lo hace!
> También funciona en muchos sabores de Unix.

... pero eso no funcionará si está buscando una sola letra (como el proceso 'X').


2

Finalmente puedo compartir este desastre de una línea que hice hace aproximadamente un año y medio ...

while read in; do host "$in"; done < sites.txt | grep -iv "GOOGLE" | grep -E '1\.2\.3\.4|5\.6\.7\.8' | sed -e 's/has\ address\ 216.70.91.72//' | sed -e 's/has\ address\ 94.23.33.92//' | while read sites; do curl -sL -w "%{http_code} %{url_effective}\\n" "$sites" -o /dev/null; done | grep -ivE '4.*|5.*' | sed -e 's/200//' | sed -e 's/HTTP/http/'

Eso...

  1. Lee sitios.txt
  2. Ejecuta "host" en cada uno (en retrospectiva, dig + short hubiera hecho esto mucho más fácil)
  3. Elimina las líneas que contienen "GOOGLE": estos son los registros mx
  4. Obtiene las líneas que tienen una de dos IP
  5. Obtiene el código de estado http de cada sitio en la lista
  6. Elimina los sitios que devuelven 4xx o 5xx
  7. Elimina el "200" de los sitios que devolvieron ese
  8. Reemplaza "HTTP" con "http" - puramente estético, sin razón real.

Apuesto a que esto podría haberse hecho mucho mejor con un solo script de Python.


Uh ... no estoy seguro de que este sea el ejemplo más limpio y fácil para explicarle las tuberías a un novato;)
Erathiel

2
Mi pregunta es, ¿cuál es su propósito?
ADTC

Tenía un archivo lleno de dominios, y necesitaba ver si estaban en uno de mis dos servidores (que "heredé", desafortunadamente). Esto lee el archivo, "aloja" y limpia esa salida, luego solo hace una solicitud para ver si devuelve un error 4xx o 5xx. Si lo hiciera, entonces descartaría el dominio; si no, los saca y los pongo en otro archivo.
curtidor

1

Esto es lo primero que me vino a la mente ...

mysqldumpes una aplicación de consola que envía datos, esquemas y opcionalmente procedimientos y funciones a stdout. Por lo general, se redirige a un archivo para respaldo.

mysqldump <options> > mydb.dump

Eso le daría un script SQL sin comprimir. Para ahorrar espacio, puede comprimirlo con bzip2.

bzip2 mydb.dump

Alternativamente, puede hacer ambas cosas en un solo paso:

mysqldump <options> | bzip2 > mydb.dump.bz2

En este ejemplo anterior, el stdout de mysqldumpse canaliza a bzip2 que luego tiene su salida redirigida a un archivo.


1
Añadir la operación inversa también: bzcat mydb.dump.bz2 | mysql <options>.
manatwork

1

Aquí hay un ejemplo que uso en mi trabajo de múltiples tuberías en un comando. Esto usa gawk para buscar el registro de consultas generales de MySQL ($ OFILE) y encontrar los inicios de sesión denegados. Luego clasifica esa lista por nombre, canaliza esa lista a uniq que cuenta las ocurrencias, y luego clasifica por última vez para ordenar la lista contada numéricamente ...

gawk '{ for (x=1;x<=NF;x++) if ( $x~"Access" && $(x+4)~".*@.*") print $(x+4)}' $OFILE | sort | uniq -c | sort -n

1

Las tuberías funcionan mejor con filtros y traductores

find /usr/bin/ |                #produce 
sed 's:.*/::'  |                #translate: strip directory part
grep -i '^z'   |                #filter   : select items starting with z
xargs -d '\n' aFinalConsumer    #consume  

De esta forma, los datos pueden fluir de un programa al siguiente en memoria intermedia y en ningún momento todos los datos tienen que estar en la memoria a la vez.


0

cat filename | less es un uso terrible de la tubería ya que solo puedes hacer less filename

Aquí hay un ejemplo de pips que uso todos los días (pero también puede ser un mal ejemplo): ls -la | more -c

Las respuestas de Scott Hoffman y Njsg son mejores ejemplos.



0

ejecute este en cualquier directorio que desee tener un análisis ordenado para el tamaño de la carpeta (luego desplácese hacia abajo con la tecla FIN):

du -m| sort -n| less

Sortiert nach Ordnergrösse


0

Aquí hay un ejemplo que utilicé para configurar la variable DISPLAY cuando xauth no era una opción ...

export DISPLAY=\`who am i |awk '{print $NF}' | sed 's/[()]//g'`":0.0"

El primer comando obtiene los datos necesarios, es decir, nombre de host o IP. El segundo comando obtiene solo esos datos (último campo). Finalmente, el último comando elimina el paréntesis de los datos.


0

Canalización de comandos que puede usar en cualquier lugar donde sienta que la salida del primer comando se puede alimentar como entrada al siguiente.

Ejemplos.

  1. Con los archivos de texto, puede pasar el archivo de texto a grep para buscar líneas de texto particulares. Luego puede pasar la salida a sed o awk para modificar o imprimir cierta parte de la línea.

ejemplo de gato txt | grep {some_line} | awk {some_command}

  1. Al trabajar con el proceso, puede usar tuberías para enviar comandos para matar el proceso.

Es simplemente el concepto de que si siente que la salida del comando que ejecutó puede ingresar otro comando, puede canalizarlos.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.