====== Streams, Pipes e Redirecionadores ====== ==== Fluxos e ligações ==== Saber trabalhar com fluxos,pipes e redirecionadores no Linux é uma obrigação de qualquer usuário e principalmente do administrador, pois essas tarefas são coisas rotineiras no dia-a-dia de qualquer um deles. ==== I/O padrão e descritores ==== A entrada e saída padrão (I/O) é a capacidade do interpretador de comandos e usada praticamente por todos os utilitários de modo texto do Linux quando da necessidade de fazer algum redirecionamento para atela ou para dentro de um arquivo qualquer. === Os três tipos de descritores mais conhecidos são: === * Entrada padrão **(stdin) Standard Input**: É o descritor que está vinculado principalmente ao teclado, ou seja, quando digitamos algo estamos enviando essas informações para a entrada padrão. Ele é conhecido como descritor de arquivos 0 (zero); * Saída padrão **(stdout) Standard Output**: É o descritor que usamos quando algum comando manda o resultado de um processamento para atela que pode ser no modo gráfico ou em um terminal qualquer. Ele é conhecido como descritor de arquivo 1; * Erro padrão **(stderr) Standard error**: É o descritor bem semelhante ao descritor 1,mas tem como especialidade receber sinais de erros, por exemplo, que o interpretador de comando gerar. Ele é útil por permitir que você separe as mensagens de erro das mensagens normais do sistema. Ele é conhecido como descritor de arquivo 2. {{:streams.png|}} ==== Dutos ==== O pipe "|", pronuncia-se "paipe", também é chamado de duto e ele simplesmente envia a saída de um comando para a entrada do próximo comando para continuidade do processamento. O uso mais comum dele é quando desejamos procurar por algo no sistema cujo resultado é maior que a tela, então, fazemos o uso de pipe com os comandos de pausa como um //ls -R / | more//, por exemplo. Para listar todos os processo por ocorrência da string gean com filtragem na tela (stdout): $ ps aux | grep gean Ou redirecionando o resultado para um arquivo $ ps aux | grep gean | tee gean.log ==== Redirecionamentos ==== === Redirecionador > (maior) === Redireciona a saída de um programa ou comando para algum dispositivo ou arquivo, em vez do dispositivo de de saída padrão (stdout) que é a tela. Esse redirecionamento cria ou substitui o conteúdo do arquivo. # ls / 1> stdout # cat stdout bin boot dev etc home initrd.img lib lost+found media mnt opt proc root run sbin srv sys tmp usr var vmlinuz === Redirecionador > (maior-maior) === Alimenta (//append//) um conteúdo ao já existente, diferente do primeiro ele não apaga o conteúdo do arquivo, caso esse arquivo já exista; o que ele faz é adicionar o resultado no final do arquivo. # ls / 1>> stdout # cat stdout bin boot dev etc home initrd.img lib lost+found media mnt opt proc root run sbin srv sys tmp usr var vmlinuz bin boot dev etc home initrd.img lib lost+found media mnt opt proc root run sbin srv sys tmp usr var vmlinuz O comando //logsave// usado como o parâmetro //-a// serve como //append//, ou seja, anexa o conteúdo no arquivo de log: # logsave ls.log ls -laF /etc/init.d/ # cat ls.log Log of ls -laF /etc/init.d/ Sat May 28 09:38:14 2016 total 252 drwxr-xr-x 2 root root 4096 Mar 1 08:55 ./ drwxr-xr-x 89 root root 4096 Mai 28 08:56 ../ -rwxr-xr-x 1 root root 2243 Nov 9 2014 acpid* -rwxr-xr-x 1 root root 2014 Dez 28 2014 anacron* -rwxr-xr-x 1 root root 10077 Out 24 2015 apache2* -rwxr-xr-x 1 root root 2948 Ago 18 2014 bluetooth* -rwxr-xr-x 1 root root 1276 Abr 6 2015 bootlogs* -rwxr-xr-x 1 root root 1248 Abr 6 2015 bootmisc.sh* -rwxr-xr-x 1 root root 3807 Abr 6 2015 checkfs.sh* -rwxr-xr-x 1 root root 1072 Abr 6 2015 checkroot-bootclean.sh* -rwxr-xr-x 1 root root 9290 Abr 6 2015 checkroot.sh* -rwxr-xr-x 1 root root 1379 Dez 8 2011 console-setup* -rwxr-xr-x 1 root root 3049 Out 23 2014 cron* -rwxr-xr-x 1 root root 2813 Jul 21 2015 dbus* -rw-r--r-- 1 root root 1345 Mar 1 08:55 .depend.boot -rw-r--r-- 1 root root 550 Mar 1 08:55 .depend.start -rw-r--r-- 1 root root 501 Mar 1 08:55 .depend.stop -rwxr-xr-x 1 root root 2078 Fev 19 11:30 didiwiki* -rwxr-xr-x 1 root root 1336 Abr 6 2015 halt* -rwxr-xr-x 1 root root 1423 Abr 6 2015 hostname.sh* -rwxr-xr-x 1 root root 3916 Mar 29 2015 hwclock.sh* -rwxr-xr-x 1 root root 8189 Out 25 2014 kbd* -rwxr-xr-x 1 root root 1591 Set 30 2012 keyboard-setup* -rwxr-xr-x 1 root root 1300 Abr 6 2015 killprocs* -rwxr-xr-x 1 root root 1990 Set 23 2014 kmod* -rwxr-xr-x 1 root root 995 Abr 6 2015 motd* -rwxr-xr-x 1 root root 677 Abr 6 2015 mountall-bootclean.sh* -rwxr-xr-x 1 root root 2138 Abr 6 2015 mountall.sh* -rwxr-xr-x 1 root root 1461 Abr 6 2015 mountdevsubfs.sh* -rwxr-xr-x 1 root root 1564 Abr 6 2015 mountkernfs.sh* -rwxr-xr-x 1 root root 685 Abr 6 2015 mountnfs-bootclean.sh* -rwxr-xr-x 1 root root 2456 Abr 6 2015 mountnfs.sh* -rwxr-xr-x 1 root root 5485 Jan 26 10:49 mysql* -rwxr-xr-x 1 root root 4760 Dez 14 2014 networking* -rwxr-xr-x 1 root root 1192 Mar 6 2015 procps* -rwxr-xr-x 1 root root 6228 Abr 6 2015 rc* -rwxr-xr-x 1 root root 820 Abr 6 2015 rc.local* -rwxr-xr-x 1 root root 117 Abr 6 2015 rcS* -rw-r--r-- 1 root root 2427 Abr 6 2015 README -rwxr-xr-x 1 root root 661 Abr 6 2015 reboot* -rwxr-xr-x 1 root root 1042 Abr 6 2015 rmnologin* -rwxr-xr-x 1 root root 4355 Jul 10 2014 rsync* -rwxr-xr-x 1 root root 2796 Ago 29 2015 rsyslog* -rwxr-xr-x 1 root root 3207 Abr 6 2015 sendsigs* -rwxr-xr-x 1 root root 597 Abr 6 2015 single* -rw-r--r-- 1 root root 1087 Abr 6 2015 skeleton -rwxr-xr-x 1 root root 4077 Mar 22 2015 ssh* -rwxr-xr-x 1 root root 6581 Ago 29 2015 udev* -rwxr-xr-x 1 root root 461 Ago 29 2015 udev-finish* -rwxr-xr-x 1 root root 2737 Abr 6 2015 umountfs* -rwxr-xr-x 1 root root 2202 Abr 6 2015 umountnfs.sh* -rwxr-xr-x 1 root root 1129 Abr 6 2015 umountroot* -rwxr-xr-x 1 root root 3111 Abr 6 2015 urandom* Sat May 28 09:38:14 2016 ---------------- === Redirecionador < (menor) === Tem a função de "receber", ou seja, enviar a instrução ao comando para que ele execute uma ação se essa for uma ação válida para o comando # tr "a-z" "A-Z" < ls.log LOG OF LS -LAF /ETC/INIT.D/ SAT MAY 28 09:38:14 2016 TOTAL 252 DRWXR-XR-X 2 ROOT ROOT 4096 MAR 1 08:55 ./ DRWXR-XR-X 89 ROOT ROOT 4096 MAI 28 08:56 ../ -RWXR-XR-X 1 ROOT ROOT 2243 NOV 9 2014 ACPID* -RWXR-XR-X 1 ROOT ROOT 2014 DEZ 28 2014 ANACRON* -RWXR-XR-X 1 ROOT ROOT 10077 OUT 24 2015 APACHE2* -RWXR-XR-X 1 ROOT ROOT 2948 AGO 18 2014 BLUETOOTH* -RWXR-XR-X 1 ROOT ROOT 1276 ABR 6 2015 BOOTLOGS* -RWXR-XR-X 1 ROOT ROOT 1248 ABR 6 2015 BOOTMISC.SH* -RWXR-XR-X 1 ROOT ROOT 3807 ABR 6 2015 CHECKFS.SH* -RWXR-XR-X 1 ROOT ROOT 1072 ABR 6 2015 CHECKROOT-BOOTCLEAN.SH* -RWXR-XR-X 1 ROOT ROOT 9290 ABR 6 2015 CHECKROOT.SH* -RWXR-XR-X 1 ROOT ROOT 1379 DEZ 8 2011 CONSOLE-SETUP* -RWXR-XR-X 1 ROOT ROOT 3049 OUT 23 2014 CRON* -RWXR-XR-X 1 ROOT ROOT 2813 JUL 21 2015 DBUS* -RW-R--R-- 1 ROOT ROOT 1345 MAR 1 08:55 .DEPEND.BOOT -RW-R--R-- 1 ROOT ROOT 550 MAR 1 08:55 .DEPEND.START -RW-R--R-- 1 ROOT ROOT 501 MAR 1 08:55 .DEPEND.STOP -RWXR-XR-X 1 ROOT ROOT 2078 FEV 19 11:30 DIDIWIKI* -RWXR-XR-X 1 ROOT ROOT 1336 ABR 6 2015 HALT* -RWXR-XR-X 1 ROOT ROOT 1423 ABR 6 2015 HOSTNAME.SH* -RWXR-XR-X 1 ROOT ROOT 3916 MAR 29 2015 HWCLOCK.SH* -RWXR-XR-X 1 ROOT ROOT 8189 OUT 25 2014 KBD* -RWXR-XR-X 1 ROOT ROOT 1591 SET 30 2012 KEYBOARD-SETUP* -RWXR-XR-X 1 ROOT ROOT 1300 ABR 6 2015 KILLPROCS* -RWXR-XR-X 1 ROOT ROOT 1990 SET 23 2014 KMOD* -RWXR-XR-X 1 ROOT ROOT 995 ABR 6 2015 MOTD* -RWXR-XR-X 1 ROOT ROOT 677 ABR 6 2015 MOUNTALL-BOOTCLEAN.SH* -RWXR-XR-X 1 ROOT ROOT 2138 ABR 6 2015 MOUNTALL.SH* -RWXR-XR-X 1 ROOT ROOT 1461 ABR 6 2015 MOUNTDEVSUBFS.SH* -RWXR-XR-X 1 ROOT ROOT 1564 ABR 6 2015 MOUNTKERNFS.SH* -RWXR-XR-X 1 ROOT ROOT 685 ABR 6 2015 MOUNTNFS-BOOTCLEAN.SH* -RWXR-XR-X 1 ROOT ROOT 2456 ABR 6 2015 MOUNTNFS.SH* -RWXR-XR-X 1 ROOT ROOT 5485 JAN 26 10:49 MYSQL* -RWXR-XR-X 1 ROOT ROOT 4760 DEZ 14 2014 NETWORKING* -RWXR-XR-X 1 ROOT ROOT 1192 MAR 6 2015 PROCPS* -RWXR-XR-X 1 ROOT ROOT 6228 ABR 6 2015 RC* -RWXR-XR-X 1 ROOT ROOT 820 ABR 6 2015 RC.LOCAL* -RWXR-XR-X 1 ROOT ROOT 117 ABR 6 2015 RCS* -RW-R--R-- 1 ROOT ROOT 2427 ABR 6 2015 README -RWXR-XR-X 1 ROOT ROOT 661 ABR 6 2015 REBOOT* -RWXR-XR-X 1 ROOT ROOT 1042 ABR 6 2015 RMNOLOGIN* -RWXR-XR-X 1 ROOT ROOT 4355 JUL 10 2014 RSYNC* -RWXR-XR-X 1 ROOT ROOT 2796 AGO 29 2015 RSYSLOG* -RWXR-XR-X 1 ROOT ROOT 3207 ABR 6 2015 SENDSIGS* -RWXR-XR-X 1 ROOT ROOT 597 ABR 6 2015 SINGLE* -RW-R--R-- 1 ROOT ROOT 1087 ABR 6 2015 SKELETON -RWXR-XR-X 1 ROOT ROOT 4077 MAR 22 2015 SSH* -RWXR-XR-X 1 ROOT ROOT 6581 AGO 29 2015 UDEV* -RWXR-XR-X 1 ROOT ROOT 461 AGO 29 2015 UDEV-FINISH* -RWXR-XR-X 1 ROOT ROOT 2737 ABR 6 2015 UMOUNTFS* -RWXR-XR-X 1 ROOT ROOT 2202 ABR 6 2015 UMOUNTNFS.SH* -RWXR-XR-X 1 ROOT ROOT 1129 ABR 6 2015 UMOUNTROOT* -RWXR-XR-X 1 ROOT ROOT 3111 ABR 6 2015 URANDOM* SAT MAY 28 09:38:14 2016 ---------------- Outros exemplos: # more < /etc/passwd root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync [...] # < /etc/passwd less === Redirecionador << (menor-menor) === # sort -k2 < 1 uva > 2 pera > 3 banana > 4 abacaxi > END 4 abacaxi 3 banana 2 pera 1 uva Usando esse redirecionado ele abre um editor com o delimitador que indica o final da edição, ou seja, quando o interpretador identificar o delimitador //END// que foi utilizado no exemplo, ele encerra a edição e exibe na saída padrão. Exemplo usando os dois redirecionadores duplo. # cat << END >> vhost.conf > > DocumentRoot /var/www/html/vhost > ErrorLog logs/vhost.error > CustomLog logs/vhost.access combined > > END # cat vhost.conf DocumentRoot /var/www/html/vhost ErrorLog logs/vhost.error CustomLog logs/vhost.access combined Nesse exemplo ao invés do outro anterior, o conteúdo digitado foi redirecionado há um arquivo. === Redirecionador 2> (dois-maior) === Tem o mesmo comportamento que o redirecionador //> (maior)//, mas com a ideia de usar mensagens de erros, ou seja, elas não serão ecoadas na tela e sim enviadas para um arquivo. # cat /etc/passwd /etc/senhas 2> error.log root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/usr/sbin/nologin man:x:6:12:man:/var/cache/man:/usr/sbin/nologin lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin mail:x:8:8:mail:/var/mail:/usr/sbin/nologin news:x:9:9:news:/var/spool/news:/usr/sbin/nologin uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin proxy:x:13:13:proxy:/bin:/usr/sbin/nologin www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin backup:x:34:34:backup:/var/backups:/usr/sbin/nologin list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin systemd-timesync:x:100:103:systemd Time Synchronization,,,:/run/systemd:/bin/false systemd-network:x:101:104:systemd Network Management,,,:/run/systemd/netif:/bin/false systemd-resolve:x:102:105:systemd Resolver,,,:/run/systemd/resolve:/bin/false systemd-bus-proxy:x:103:106:systemd Bus Proxy,,,:/run/systemd:/bin/false messagebus:x:104:109::/var/run/dbus:/bin/false avahi-autoipd:x:105:111:Avahi autoip daemon,,,:/var/lib/avahi-autoipd:/bin/false sshd:x:106:65534::/var/run/sshd:/usr/sbin/nologin gean:x:1000:1000:Gean Martins,,,:/home/gean:/bin/bash didiwiki:x:107:113:DidiWiki,,,:/var/lib/didiwiki:/bin/false mysql:x:108:115:MySQL Server,,,:/nonexistent:/bin/false # cat error.log cat: /etc/senhas: Arquivo ou diretório não encontrado === Redirecionador 2>> (dois-maior-maior) === Usado para alimentar o arquivo de erro: # cat /etc/passwd /etc/senhas 2>> error.log root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/usr/sbin/nologin man:x:6:12:man:/var/cache/man:/usr/sbin/nologin lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin mail:x:8:8:mail:/var/mail:/usr/sbin/nologin news:x:9:9:news:/var/spool/news:/usr/sbin/nologin uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin proxy:x:13:13:proxy:/bin:/usr/sbin/nologin www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin backup:x:34:34:backup:/var/backups:/usr/sbin/nologin list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin systemd-timesync:x:100:103:systemd Time Synchronization,,,:/run/systemd:/bin/false systemd-network:x:101:104:systemd Network Management,,,:/run/systemd/netif:/bin/false systemd-resolve:x:102:105:systemd Resolver,,,:/run/systemd/resolve:/bin/false systemd-bus-proxy:x:103:106:systemd Bus Proxy,,,:/run/systemd:/bin/false messagebus:x:104:109::/var/run/dbus:/bin/false avahi-autoipd:x:105:111:Avahi autoip daemon,,,:/var/lib/avahi-autoipd:/bin/false sshd:x:106:65534::/var/run/sshd:/usr/sbin/nologin gean:x:1000:1000:Gean Martins,,,:/home/gean:/bin/bash didiwiki:x:107:113:DidiWiki,,,:/var/lib/didiwiki:/bin/false mysql:x:108:115:MySQL Server,,,:/nonexistent:/bin/false # cat error.log cat: /etc/senhas: Arquivo ou diretório não encontrado cat: /etc/senhas: Arquivo ou diretório não encontrado ==== Redirecionadores com /dev/null ==== O uso do /dev/null, também conhecido como buraco negro (bit bucket) ou dispositivo nulo, é muito comum no Linux. Ele é um arquivo especial que descarta toda informação escrita/enviada para ele e não retorna qualquer informação para um processo que o leia. Exemplo enviando as mensagens de erro para esse arquivo: # find / -user gean 2> /dev/null Mensagens de saída para o buraco negro # find / -user gean 1> /dev/null find: `/proc/1214/task/1214/fd/5': Arquivo ou diretório não encontrado find: `/proc/1214/task/1214/fdinfo/5': Arquivo ou diretório não encontrado find: `/proc/1214/fd/5': Arquivo ou diretório não encontrado find: `/proc/1214/fdinfo/5': Arquivo ou diretório não encontrado Mensagens de erro para o buraco negro # find / -user gean 2> /dev/null /proc/1047 /proc/1047/task /proc/1047/task/1047 /proc/1047/task/1047/attr /proc/1047/net /proc/1047/attr [...] Enviando os dois ao mesmo tempo # find / -user gean 1> /dev/null 2> /dev/null Exemplo de script para transforma todos os arquivo do diretório de maiúsculas para minúsculas # cat << END >> renomeiafile.sh > #!/bin/bash > for file in * > do > mv $file `echo $file | tr [:upper:] [:lower:]` 2> /dev/null > done > END Para enviar as mensagens para um único arquivo: # ls /tmp/ /tempo > todo 2>&1 ==== Redirecionadores com /dev/zero, /dev/random ==== O uso desse redirecionamento comumente usado com o comando //dd// também é comum no Linux, o /dev/zero é um arquivo especial que fornece caracteres nulos, o da tabela ASCII, o NULL (código de controle 0x00) e não o número 0 (zero) que tem o código 0x30 na tabela. O fluxo de caracteres gerado por esse dispositivo pode, por exemplo, ser utilizado para sobrescrever informações ou para gerar um arquivo limpo de certo tamanho. Para sobrescrever totalmente uma partição: # dd if=/dev/zero of=/dev/sda1 Quando necessário é possível criar um arquivo vazio especificando o tamanho do bloco e quantas vezes isso acontece. A multiplicação do bloco com o número de vezes resulta no tamanho do arquivo: # dd if=/dev/zero of=/tmp/teste.img bs=2048 count=20000 20000+0 registros de entrada 20000+0 registros de saída 40960000 bytes (41 MB) copiados, 0,237271 s, 173 MB/s # du -sch /tmp/teste.img 40M /tmp/teste.img 40M total # cat /dev/null > /tml/vazio1 # cat /dev/zero > /tmp/vazio2 O primeiro comando é uma forma de criar um arquivo vazio com 0 (zoro) bytes, mas no segundo, como ele é indefinido, o arquivo crescerá com zeros dentro dele até acabar com o espaço físico do disco ou partição. O /dev/random também é um arquivoespecial que serve como um gerador de números pseudo-aleatórios. Também podemos usar o /dev/urandom para gerar sementes aleatórias de alta qualidade. Exemplo para limpar um disco: # dd if=/dev/urandom of=/dev/sda1 Exemplo para criar chaves SSL e WEP: # dd if=/dev/random bs=1 count=32 2> /dev/null | xxd -ps f8064f3eca754db272a65b5e559992fd5e7fdb3a97838f449238208b130c 06b0 # dd if=/dev/random bs=1 count=32 2> /dev/null | hexdump 0000000 222d 1ed1 3049 f6e6 d650 a2ba d3d7 f176 0000010 ac39 1f7c 5b21 45eb 0178 3cc8 d2e4 73e1 0000020 A contagem aqui é importante, pois é ela quem define o tamanho da chave a ser criada. Veja que para gerar uma chave de 40 bits: count=5, 64 bits: count=8, 104 bits: count=13, 128 bits: count=16, 152 bits: count=19, 232 bitis: count=29, e 256 bits: count=32. # dd if=/dev/random bs=1 count=5 2> /dev/null | xxd -ps 900b9651ee # dd if=/dev/random bs=1 count=8 2> /dev/null | xxd -ps be597e9eb14f63e9 # dd if=/dev/random bs=1 count=13 2> /dev/null | xxd -ps dcbb73f7c38c518bac9a466b90 # dd if=/dev/random bs=1 count=16 2> /dev/null | xxd -ps 42302c313074e4c7fd2bf1e5afe724ff # dd if=/dev/random bs=1 count=19 2> /dev/null | xxd -ps ab24fa7546297c111e937b259158b94fc55a8b $ dd if=/dev/random bs=1 count=29 2> /dev/null | xxd -ps fc3abe0f9279a5c6e4d5bb0b85c8e2e1a1bda538305069b6ecb42855c8 $ dd if=/dev/random bs=1 count=32 2> /dev/null | xxd -ps 07d51fe1d285ffedfbee30a7787075c8e4ab169844c89f8eac401eb23e0e d415 Referências: - [[http://www.bluesock.org/~willg/dev/ascii.html]] - Linux Fundamentos, Prática e Certificação LPI - BONAN, Adilson. Alta Books, Rio de Janeiro/RJ, 2010