Linux Professional Institute Learning Logo.
Ir para o conteúdo principal
  • Home
    • Todos os recursos
    • LPI Materiais Didáticos
    • Colabore Conosco
    • Publishing Partners
    • Seja um Publishing Partner
    • Quem Somos
    • FAQ
    • Colaboradores
    • Contato
  • LPI.org
103.4 Lição 2
Tópico 101: Arquitetura de Sistema
101.1 Identificar e editar configurações de hardware
  • 101.1 Lição 1
101.2 Início (boot) do sistema
  • 101.2 Lição 1
101.3 Alternar runlevels/boot targets, desligar e reiniciar o sistema
  • 101.3 Lição 1
Tópico 102: Instalação do Linux e administração de Pacotes
102.1 Dimensionar partições de disco
  • 102.1 Lição 1
102.2 Instalar o gerenciador de inicialização
  • 102.2 Lição 1
102.3 Controle de bibliotecas compartilhadas
  • 102.3 Lição 1
102.4 Utilização do sistema de pacotes Debian
  • 102.4 Lição 1
102.5 Utilização do sistema de pacotes RPM e YUM
  • 102.5 Lição 1
102.6 Linux virtualizado
  • 102.6 Lição 1
Tópico 103: Comandos GNU e Unix
103.1 Trabalhar na linha de comando
  • 103.1 Lição 1
  • 103.1 Lição 2
103.2 Processar fluxos de texto usando filtros
  • 103.2 Lição 1
103.3 Gerenciamento básico de arquivos
  • 103.3 Lição 1
  • 103.3 Lição 2
103.4 Fluxos, pipes (canalização) e redirecionamentos de saída
  • 103.4 Lição 1
  • 103.4 Lição 2
103.5 Criar, monitorar e finalizar processos
  • 103.5 Lição 1
  • 103.5 Lição 2
103.6 Modificar a prioridade de execução de um processo
  • 103.6 Lição 1
103.7 Procurar em arquivos de texto usando expressões regulares
  • 103.7 Lição 1
  • 103.7 Lição 2
103.8 Edição básica de arquivos com o vi
  • 103.8 Lição 1
Tópico 104: Dispositivos, sistemas de arquivos Linux e padrão FHS
104.1 Criar partições e sistemas de arquivos
  • 104.1 Lição 1
104.2 Manutenção da integridade de sistemas de arquivos
  • 104.2 Lição 1
104.3 Controle da montagem e desmontagem dos sistemas de arquivos
  • 104.3 Lição 1
104.5 Controlar permissões e propriedades de arquivos
  • 104.5 Lição 1
104.6 Criar e alterar links simbólicos e hardlinks
  • 104.6 Lição 1
104.7 Encontrar arquivos de sistema e conhecer sua localização correta
  • 104.7 Lição 1
How to get certified
  1. Tópico 103: Comandos GNU e Unix
  2. 103.4 Fluxos, pipes (canalização) e redirecionamentos de saída
  3. 103.4 Lição 2

103.4 Lição 2

Certificação:

LPIC-1

Versão:

5.0

Tópico:

103 Comandos GNU e Unix

Objetivo:

103.4 Usando fluxos, pipes e redirecionamentos

Lição:

2 de 2

Introdução

Um aspecto da filosofia Unix afirma que cada programa precisa ter um propósito específico e não deve tentar incorporar recursos fora de seu escopo. Mas manter as coisas simples não significa que os resultados serão menos elaborados, já que diferentes programas podem ser encadeados para produzir uma saída combinada. O caractere de barra vertical |, também conhecido como símbolo pipe, pode ser usado para criar uma canalização (pipeline) conectando a saída de um programa diretamente à entrada de outro programa, ao passo que a substituição de comandos permite armazenar a saída de um programa em uma variável ou usá-lo diretamente como argumento para outro comando.

Pipes

Ao contrário dos redirecionamentos, com os pipes os dados fluem da esquerda para a direita na linha de comando e o destino é outro processo, não um caminho do sistema de arquivos, descritor de arquivo ou Here document. O caractere de barra vertical | manda o shell iniciar todos os comandos distintos ao mesmo tempo e conectar a saída do comando anterior à entrada do comando seguinte, da esquerda para a direita. Por exemplo, em vez de usar redirecionamentos, o conteúdo do arquivo /proc/cpuinfo enviado para a saída padrão por cat pode ser canalizado para o stdin de wc com o seguinte comando:

$ cat /proc/cpuinfo | wc
   208    1184    6096

Na ausência do caminho para um arquivo, wc conta o número de linhas, palavras e caracteres que recebe em seu stdin, como é o caso no exemplo. Muitos pipes podem estar presentes em um comando composto. No exemplo a seguir, dois pipes são usados:

$ cat /proc/cpuinfo | grep 'model name' | uniq
model name      : Intel(R) Xeon(R) CPU           X5355  @ 2.66GHz

O conteúdo do arquivo /proc/cpuinfo produzido por cat /proc/cpuinfo foi canalizado para o comando grep 'model name', que em seguida seleciona apenas as linhas contendo o termo model name. A máquina que executa o exemplo tem muitas CPUs, portanto existem linhas repetidas com model name. O último pipe conecta grep 'model name' ao uniq, que é responsável por pular qualquer linha idêntica à anterior.

Os pipes podem ser combinados com redirecionamentos na mesma linha de comando. O exemplo anterior pode ser reescrito em uma forma mais simples:

$ grep 'model name' </proc/cpuinfo | uniq
model name      : Intel(R) Xeon(R) CPU           X5355  @ 2.66GHz

O redirecionamento de entrada para grep não é estritamente necessário, pois grep aceita um caminho de arquivo como argumento, mas o exemplo demonstra como construir comandos combinados.

Pipes e redirecionamentos são exclusivos, ou seja, uma origem pode ser mapeada para apenas um destino. Ainda assim, é possível redirecionar uma saída para um arquivo e ainda vê-la na tela com o programa tee. Para isso, o primeiro programa envia sua saída para o stdin de tee e um nome de arquivo é fornecido a este último para armazenar os dados:

$ grep 'model name' </proc/cpuinfo | uniq | tee cpu_model.txt
model name      : Intel(R) Xeon(R) CPU           X5355  @ 2.66GHz
$ cat cpu_model.txt
model name      : Intel(R) Xeon(R) CPU           X5355  @ 2.66GHz

A saída do último programa na cadeia, gerada por uniq, é exibida e armazenada no arquivo cpu_model.txt. Para não sobrescrever o conteúdo do arquivo fornecido, e sim anexar dados a ele, a opção -a deve ser fornecida para tee.

Apenas a saída padrão de um processo é capturada por um pipe. Digamos que você precise passar por um longo processo de compilação na tela e, ao mesmo tempo, salvar tanto a saída padrão quanto o erro padrão em um arquivo para inspeção posterior. Supondo que seu diretório atual não tenha um Makefile, o seguinte comando gerará um erro:

$ make | tee log.txt
make: *** No targets specified and no makefile found.  Stop.

Embora exibida na tela, a mensagem de erro gerada por make não foi capturada por tee e o arquivo log.txt foi criado vazio. É preciso fazer um redirecionamento antes que um pipe possa capturar o stderr:

$ make 2>&1 | tee log.txt
make: *** No targets specified and no makefile found.  Stop.
$ cat log.txt
make: *** No targets specified and no makefile found.  Stop.

Neste exemplo, o stderr de make foi redirecionado para o stdout, de forma que o tee foi capaz de capturá-lo com um pipe, exibi-lo na tela e salvá-lo no arquivo log.txt. Em casos como esse, pode ser útil salvar as mensagens de erro para inspeção posterior.

Substituição de comando

Outro método para capturar a saída de um comando é a substituição de comando. Ao colocar um comando entre crases, o Bash o substitui por sua saída padrão. O exemplo a seguir mostra como usar o stdout de um programa como argumento para outro programa:

$ mkdir `date +%Y-%m-%d`
$ ls
2019-09-05

A saída do programa date, a data atual formatada como ano-mês-dia, foi usada como um argumento para criar um diretório com o mkdir. Um resultado idêntico é obtido usando $() em vez de crases:

$ rmdir 2019-09-05
$ mkdir $(date +%Y-%m-%d)
$ ls
2019-09-05

O mesmo método pode ser usado para armazenar a saída de um comando como uma variável:

$ OS=`uname -o`
$ echo $OS
GNU/Linux

O comando uname -o retorna o nome genérico do sistema operacional atual, que foi armazenado na variável de sessão OS. Atribuir a saída de um comando a uma variável é muito útil em scripts, possibilitando armazenar e avaliar os dados de várias maneiras distintas.

Dependendo da saída gerada pelo comando substituído, a substituição do comando interno do shell pode não ser apropriada. Um método mais sofisticado para usar a saída de um programa como argumento de outro programa emprega um intermediário chamado xargs. O programa xargs usa o conteúdo que recebe via stdin para executar um determinado comando com o conteúdo como argumento. O exemplo a seguir mostra o xargs executando o programa identify com argumentos fornecidos pelo programa find:

$ find /usr/share/icons -name 'debian*' | xargs identify -format "%f: %wx%h\n"
debian-swirl.svg: 48x48
debian-swirl.png: 22x22
debian-swirl.png: 32x32
debian-swirl.png: 256x256
debian-swirl.png: 48x48
debian-swirl.png: 16x16
debian-swirl.png: 24x24
debian-swirl.svg: 48x48

O programa identify é parte do ImageMagick, um conjunto de ferramentas de linha de comando para inspecionar, converter e editar a maioria dos tipos de arquivo de imagem. No exemplo, o xargs pegou todos os caminhos listados por find e os colocou como argumentos para identify, que então exibe as informações para cada arquivo formatado conforme exigido pela opção -format. Os arquivos encontrados pelo find no exemplo são imagens contendo o logotipo da distribuição em um sistema de arquivos Debian. -format é um parâmetro para identify, não para xargs.

A opção -n 1 exige que o xargs execute o comando fornecido com apenas um argumento por vez. No caso do exemplo, em vez de passar todos os caminhos encontrados por find como uma lista de argumentos para identify, o uso de xargs -n 1 executaria o comando identify para cada caminho separadamente. Usar -n 2 executaria o identify com dois caminhos como argumentos, -n 3 com três caminhos como argumentos e assim por diante. Da mesma forma, quando o xargs processa conteúdos com várias linhas — como é o caso com a entrada fornecida por find — a opção -L pode ser usada para limitar quantas linhas serão usadas como argumentos por execução do comando.

Note

Pode ser desnecessário usar o xargs com a opção -n 1 ou -L 1 para processar a saída gerada pelo find. O comando find tem a opção -exec para executar um comando determinado para cada item do resultado da busca.

Se os caminhos contiverem caracteres de espaço, é importante executar o find com a opção -print0. Esta opção instrui o find a usar um caractere nulo entre cada entrada para que a lista possa ser analisada corretamente por xargs (a saída foi suprimida):

$ find . -name '*avi' -print0 -o -name '*mp4' -print0 -o -name '*mkv' -print0 | xargs -0 du | sort -n

A opção -0 diz ao xargs que o caractere nulo deve ser usado como separador. Dessa forma, os caminhos de arquivo fornecidos pelo find são analisados corretamente, mesmo se contiverem espaços em branco ou outros caracteres especiais. O exemplo anterior mostra como usar o comando du para descobrir o uso de espaço em disco por cada arquivo encontrado e em seguida classificar os resultados por tamanho. A saída foi suprimida para fins de concisão. Observe que para cada critério de pesquisa é necessário incluir a opção -print0 para find.

Por padrão, o xargs coloca por último os argumentos do comando executado. Para mudar esse comportamento, usamos a opção -I:

$ find . -mindepth 2 -name '*avi' -print0 -o -name '*mp4' -print0 -o -name '*mkv' -print0 | xargs -0 -I PATH mv PATH ./

No último exemplo, todo arquivo encontrado por find é movido para o diretório atual. Como o(s) caminho(s) de origem devem ser informados para o mv antes do caminho de destino, um termo de substituição é dado à opção -I do xargs, que é então apropriadamente colocado junto a mv. Ao usar o caractere nulo como separador, não é necessário colocar o termo de substituição entre aspas.

Exercícios Guiados

  1. É conveniente salvar a data de execução das ações realizadas por scripts automáticos. O comando date +%Y-%m-%d mostra a data atual no formato ano-mês-dia. Como a saída desse comando pode ser armazenada em uma variável do shell chamada TODAY usando a substituição de comando?

  2. Usando o comando echo, como o conteúdo da variável TODAY pode ser enviado para a saída padrão do comando sed s/-/./g?

  3. Como a saída do comando date +%Y-%m-%d pode ser usada como uma Here string para o comando sed s/-/./g?

  4. O comando convert image.jpeg -resize 25% small/image.jpeg cria uma versão menor de image.jpeg e coloca a imagem resultante em um arquivo com o mesmo nome dentro do subdiretório small. Usando o xargs, como é possível executar o mesmo comando para todas as imagens listadas no arquivo filelist.txt?

Exercícios Exploratórios

  1. Uma rotina de backup simples cria periodicamente uma imagem da partição /dev/sda1 com dd < /dev/sda1 > sda1.img. Para realizar futuras verificações de integridade de dados, a rotina também gera um hash SHA1 do arquivo com sha1sum < sda1.img > sda1.sha1. Adicionando pipes e o comando tee, como esses dois comandos poderiam ser combinados em um só?

  2. O comando tar é usado para empacotar muitos arquivos em um só, preservando a estrutura de diretórios. A opção -T permite especificar um arquivo contendo os caminhos a arquivar. Por exemplo, find /etc -type f | tar -cJ -f /srv/backup/etc.tar.xz -T - cria o arquivo tar compactado etc.tar.xz a partir da lista fornecida pelo comando find (a opção -T - indica a entrada padrão como a lista de caminhos). Para evitar possíveis erros de análise devido a caminhos que contêm espaços, quais opções deveriam estar presentes para os comandos find e tar?

  3. Em vez de abrir uma nova sessão remota do shell, o comando ssh pode simplesmente executar um comando indicado como argumento: ssh user@storage "remote command". Dado que ssh também permite redirecionar a saída padrão de um programa local para a entrada padrão do programa remoto, como o comando cat canalizaria um arquivo local chamado etc.tar.gz para /srv/backup/etc.tar.gz em user@storage através de ssh?

Resumo

Esta lição cobre as técnicas tradicionais de comunicação entre processos empregadas pelo Linux. A canalização de comandos cria um canal de comunicação unilateral entre dois processos e a substituição de comandos permite armazenar a saída de um processo em uma variável shell. A lição passa pelas seguintes etapas:

  • Como pipes podem ser usados para transmitir a saída de um processo para a entrada de outro processo.

  • A finalidade dos comandos tee e xargs.

  • Como capturar a saída de um processo com a substituição de comando, armazenando-a em uma variável ou usando-a diretamente como parâmetro para outro comando.

Os comandos e procedimentos abordados foram:

  • Canalização de comandos com |.

  • Substituição de comandos com crases e $().

  • Os comandos tee, xargs e find.

Respostas aos Exercícios Guiados

  1. É conveniente salvar a data de execução das ações realizadas por scripts automáticos. O comando date +%Y-%m-%d mostra a data atual no formato ano-mês-dia. Como a saída desse comando pode ser armazenada em uma variável do shell chamada TODAY usando a substituição de comando?

    $ TODAY=`date +%Y-%m-%d`

    ou

    $ TODAY=$(date +%Y-%m-%d)
  2. Usando o comando echo, como o conteúdo da variável TODAY pode ser enviado para a saída padrão do comando sed s/-/./g?

    $ echo $TODAY | sed s/-/./g
  3. Como a saída do comando date +%Y-%m-%d pode ser usada como uma Here string para o comando sed s/-/./g?

    $ sed s/-/./g <<< `date +%Y-%m-%d`

    ou

    $ sed s/-/./g <<< $(date +%Y-%m-%d)
  4. O comando convert image.jpeg -resize 25% small/image.jpeg cria uma versão menor de image.jpeg e coloca a imagem resultante em um arquivo com o mesmo nome dentro do subdiretório small. Usando o xargs, como é possível executar o mesmo comando para todas as imagens listadas no arquivo filelist.txt?

    $ xargs -I IMG convert IMG -resize 25% small/IMG < filelist.txt

    ou

    $ cat filelist.txt | xargs -I IMG convert IMG -resize 25% small/IMG

Respostas aos Exercícios Exploratórios

  1. Uma rotina de backup simples cria periodicamente uma imagem da partição /dev/sda1 com dd < /dev/sda1 > sda1.img. Para realizar futuras verificações de integridade de dados, a rotina também gera um hash SHA1 do arquivo com sha1sum < sda1.img > sda1.sha1. Adicionando pipes e o comando tee, como esses dois comandos poderiam ser combinados em um só?

    # dd < /dev/sda1 | tee sda1.img | sha1sum > sda1.sha1
  2. O comando tar é usado para empacotar muitos arquivos em um só, preservando a estrutura de diretórios. A opção -T permite especificar um arquivo contendo os caminhos a arquivar. Por exemplo, find /etc -type f | tar -cJ -f /srv/backup/etc.tar.xz -T - cria o arquivo tar compactado etc.tar.xz a partir da lista fornecida pelo comando find (a opção -T - indica a entrada padrão como a lista de caminhos). Para evitar possíveis erros de análise devido a caminhos que contêm espaços, quais opções deveriam estar presentes para os comandos find e tar?

    Options -print0 and --null:

    $ find /etc -type f -print0 | tar -cJ -f /srv/backup/etc.tar.xz --null -T -
  3. Em vez de abrir uma nova sessão remota do shell, o comando ssh pode simplesmente executar um comando indicado como argumento: ssh user@storage "remote command". Dado que ssh também permite redirecionar a saída padrão de um programa local para a entrada padrão do programa remoto, como o comando cat canalizaria um arquivo local chamado etc.tar.gz para /srv/backup/etc.tar.gz em user@storage através de ssh?

    $ cat etc.tar.gz | ssh user@storage "cat > /srv/backup/etc.tar.gz"

    or

    $ ssh user@storage "cat > /srv/backup/etc.tar.gz" < etc.tar.gz

Linux Professional Insitute Inc. Todos os direitos reservados. Visite o site dos Materiais Didáticos: https://learning.lpi.org
31/5000 Este trabalho está licenciado sob a Licença Creative Commons Atribuição-Uso Não-Comercial-NãoDerivativos 4.0 Internacional.

Próxima Lição

103.5 Criar, monitorar e finalizar processos (103.5 Lição 1)

Ir para a próxima lição

Linux Professional Insitute Inc. Todos os direitos reservados. Visite o site dos Materiais Didáticos: https://learning.lpi.org
31/5000 Este trabalho está licenciado sob a Licença Creative Commons Atribuição-Uso Não-Comercial-NãoDerivativos 4.0 Internacional.

A LPI é uma organização sem fins lucrativos.

© 2023 O Linux Professional Institute (LPI) é um organismo de apoio aos profissionais de Open Source e referência mundial em certificação. Com mais de 200.000 pessoas certificadas, somos o principal organismo de certificação independente para Linux e Open Source do mundo. O LPI certificou profissionais de mais de 180 países, oferece exames em diversos idiomas e tem centenas de parcerias de formação em todo o globo.

Nossa missão é proporcionar oportunidades econômicas e criativas para todos, tornando universalmente acessível a certificação de conhecimentos e competências em matéria de Open Source.

  • LinkedIn
  • flogo-RGB-HEX-Blk-58 Facebook
  • Twitter
  • Entre em Contato
  • Política de Privacidade e Cookies

Encontrou um erro ou quer ajudar a aprimorar esta página? Escreva pra nós.

© 1999–2023 The Linux Professional Institute Inc. Todos os direitos reservados.