O que é um bom exemplo de comandos de tubulação juntos?

31

Se você estivesse ajudando alguém a aprender o conceito de pipes na linha de comando, qual exemplo você usaria? O exemplo que realmente surgiu foi o seguinte:

cat whatever.txt | less

Eu sinto que esse não é o melhor exemplo, porque há apenas um passo. O que é um uso bom, mas fundamental, de | ?

Idealmente, o exemplo que apresentarei usará programas que possuem saídas que podem ser executadas de forma independente e, em seguida, exibidas juntas.

    
por Matthew 03.02.2012 / 17:52

14 respostas

32

Vou orientar você em um exemplo um tanto complexo, com base em um cenário da vida real.

Problema

Digamos que o comando conky parou de responder na minha área de trabalho e eu quero eliminá-lo manualmente. Eu conheço um pouco do Unix, então sei que o que preciso fazer é executar o comando kill <PID> . Para recuperar o PID, posso usar ps ou top ou qualquer ferramenta que minha distribuição Unix tenha me dado. Mas como posso fazer isso em um comando?

Resposta

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

AVISO LEGAL: Este comando só funciona em certos casos. Não copie / cole no seu terminal e comece a usá-lo, ele pode matar processos sem suspeita. Em vez disso, aprenda como criá-lo .

Como funciona

1 ps aux

Este comando irá mostrar a lista de processos em execução e algumas informações sobre eles. A informação interessante é que ele irá mostrar o PID de cada processo em sua segunda coluna. Aqui está um extrato da saída do comando na minha caixa:

$ 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

Estou interessado apenas em um processo, por isso uso grep para encontrar a entrada correspondente ao meu 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 você pode ver na etapa 2, o comando ps gerará o processo grep conky em sua lista (afinal, é um processo em execução). Para filtrar, posso executar grep -v grep . A opção -v indica grep para corresponder a todas as linhas excluindo as que contêm o padrão.

$ ps aux | grep conky | grep -v grep
 rahmu     1948  0.2  0.0 276000  3564 ?        Sl   11:55   0:39 conky -q
NB: Eu adoraria saber uma maneira de executar as etapas 2 e 3 em uma única chamada grep .

4 awk '{print $2}'

Agora que isolei meu processo de segmentação. Eu quero recuperar seu PID. Em outras palavras, quero recuperar a segunda palavra da saída. Para minha sorte, a maioria (todos?) Dos unices modernos fornecerão alguma versão do awk , uma linguagem de script que faz maravilhas com dados tabulares. Nossa tarefa se torna tão fácil quanto print $2 .

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

5 xargs kill

Eu tenho o PID. Tudo que preciso é passá-lo para kill . Para fazer isso, usarei xargs .

xargs kill lerá a entrada (no nosso caso a partir do canal), formará um comando consistindo de kill <items> ( <items> são o que for lido na entrada) e, em seguida execute o comando criado. No nosso caso, ele executará kill 1948 . Missão cumprida.

Palavras finais

Observe que, dependendo da versão do unix que você está usando, alguns programas podem se comportar de maneira um pouco diferente (por exemplo, ps pode gerar o PID na coluna $ 3). Se algo parecer errado ou diferente, leia a documentação do seu fornecedor (ou melhor, as man páginas). Também tenha cuidado, pois tubos longos podem ser perigosos. Não faça suposições, especialmente ao usar comandos como kill ou rm . Por exemplo, se houver outro usuário chamado 'conky' (ou 'Aconkyous'), meu comando também pode matar todos os processos em execução dele!

O que estou dizendo é que seja cuidadoso, especialmente para tubos longos. É sempre melhor construí-lo interativamente como fizemos aqui, do que fazer suposições e lamentar mais tarde.

    
por 04.02.2012 / 17:32
14

Meu favorito é esse aqui:

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

faz o download de um vídeo do determinado URL do youtube passado por $1 e o envia como o arquivo fornecido por $2 . Observe como o arquivo está silenciosamente -q output para STDOUT -o - , canalizado para ffmpeg e usado como entrada por -i - .

Especialmente para novatos do Linux, isso pode ser um exemplo prático de como a linha de comando pode ser útil e facilitar as coisas do que usar ferramentas GUI. Não tenho certeza de quanto tempo levaria para baixar um vídeo do youtube e converter seu som para um mp3. A linha acima pode fazer isso em alguns segundos.

    
por 03.02.2012 / 20:02
9

O uso geral (leia-se: a maneira que eu uso na maioria das vezes) é quando, por algum motivo, eu tenho que executar alguns dados através de várias ferramentas para realizar diferentes tarefas de processamento.

Então eu diria que o uso de pipes é o mesmo que juntar vários blocos de construção (as diferentes ferramentas UNIX) juntos. Como Ulrich disse, sort e uniq é uma estrofe comum.

Dependendo do público, se você quiser destacar esse uso de pipes, você poderia, por exemplo, começar com: "Ei, este syllabus tem links para vários PDFs interessantes com papéis e notas de aula, mas alguns deles são repetidos posso de alguma forma automatizar isso? "

Você pode mostrar como lynx --dump --listonly obtém a lista de links, como grep poderia filtrar os links que terminam em .pdf , como colrm ou sed poderia se livrar dos números lynx escreve à esquerda para cada URL, como sort e uniq poderiam se livrar de duplicatas e, finalmente, como wget -i - pode ser usado para recuperar os arquivos (usando --wait para ser gentil com o servidor, é claro).

Receio que este seja um exemplo complexo. Por outro lado, pode ajudar a mostrar o poder dos pipes quando você apenas canaliza e faz com que o shell execute tudo de uma vez.

    
por 03.02.2012 / 18:22
2

Eu não sei exatamente bem, mas percorrer grep tem que ser um dos usos mais comuns, possivelmente seguido por wc -l . (Sim, grep tem o pouco conhecido interruptor -c .)

Outra sub-rotina comum é | sort | uniq , apenas porque uniq requer que sua entrada seja classificada.

    
por 03.02.2012 / 18:02
2

Não é necessário para este exemplo, mas:

$ ps aux | grep -v grep | grep conky

... inverter a ordem dos greps preserva a colorização, mas é MUITO menos eficiente. presumivelmente em listas grandes, a cor não importaria.

também, esta página da Web sugere:

link

>Johnsyweb answered Feb 21 '12 at 10:31
>The usual trick is this:
>ps aux | grep '[t]erminal'
>This will match lines containing terminal, which grep '[t]erminal' does not!
>It also works on many flavours of Unix.

... mas isso não funcionará se você estiver buscando uma única letra (como o processo 'X').

    
por 26.11.2013 / 15:39
2

Eu finalmente consegui compartilhar essa bagunça de um oneliner que fiz há cerca de um ano e meio atrás ...

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/'

É ...

  1. Lê sites.txt
  2. Executa "host" em cada uma delas (em retrospectiva, dig + short teria facilitado muito isso)
  3. Remove as linhas que contêm "GOOGLE" - estes são os registros MX
  4. Obtém as linhas que possuem um dos dois IPs
  5. Obtém o código de status http de cada site na lista
  6. Remove os sites que retornam 4xx ou 5xx
  7. Retira o "200" dos sites que retornaram que
  8. Substitui "HTTP" por "http" - puramente estético, sem motivo real.

Isso poderia ter sido feito muito melhor com um único script Python, aposto.

    
por 08.10.2015 / 15:13
1

Esta é a primeira coisa que me veio à mente ...

mysqldump é um aplicativo de console que envia dados, esquemas e, opcionalmente, procedimentos e funções para stdout. Normalmente, ele é redirecionado para um arquivo para backup.

mysqldump <options> > mydb.dump

Isso forneceria um script SQL descompactado. Para economizar espaço, você pode compactá-lo com o bzip2.

bzip2 mydb.dump

Como alternativa, você pode fazer as duas coisas em uma etapa:

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

Neste exemplo acima, o stdout de mysqldump é canalizado para o bzip2, que então tem sua saída redirecionada para um arquivo.

    
por 03.02.2012 / 19:58
1

Aqui está um exemplo que eu uso no meu trabalho de vários canais em um comando. Isso usa o gawk para procurar o log de consulta geral do MySQL ($ OFILE) e encontrar logins negados. Em seguida, ordena essa lista pelo nome, canaliza essa lista para uniq, o que conta as ocorrências e, em seguida, canaliza-a para classificar uma última vez para ordenar numericamente a lista contada ...

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

Os tubos funcionam melhor com filtros e tradutores

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

Dessa forma, os dados podem fluir de um programa para o próximo buffer e, em nenhum momento, todos os dados precisam estar na memória de uma só vez.

    
por 07.02.2016 / 14:13
0

cat filename | less é um uso terrível de tubulações, já que você pode fazer less filename

Aqui está um exemplo de pips que uso todos os dias (mas também pode ser um mau exemplo): ls -la | more -c

As respostas de scott hoffman e njsg são exemplos melhores.

    
por 03.02.2012 / 20:34
0

Que tal: pesquisa de padrões e exibir as últimas ocorrências padrão?

Mostra como usar tail , sed e grep em um contexto de canal que pode ser construído passo a passo.

    
por 26.11.2013 / 17:08
0

execute este em qualquer diretório que você queira ter uma análise ordenada para o tamanho da pasta (então role para baixo com a tecla END):

du -m| sort -n| less

Classificar mais em Ordnergrösse

    
por 07.02.2016 / 13:37
0

Aqui está um exemplo que usei para definir a variável DISPLAY quando o xauth não era uma opção ...

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

O primeiro comando obtém os dados necessários, isto é, hostname ou IP. O segundo comando obtém apenas esses dados (último campo). Finalmente, o último comando retira parênteses dos dados.

    
por 03.02.2012 / 19:21
0

Comando de tubulação você pode usar em qualquer lugar que você sentir que a saída do primeiro comando pode ser alimentada como entrada para a próxima.

Exemplos.

  1. Com arquivos de texto, você pode passar o arquivo de texto para o grep para encontrar linhas de texto específicas. Então você pode passar a saída para sed ou awk para modificar ou imprimir determinada parte da linha.

cat example txt | grep {some_line} | awk {some_command}

  1. Trabalhando com o processo, você pode usar a tubulação para enviar comandos para matar o processo.

É simplesmente o conceito de que, se você sentir que a saída do comando que você executou pode ser a entrada de outro comando, você poderá canalizá-los.

    
por 07.02.2016 / 14:26