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.
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.
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
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
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 ----------------
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
# sort -k2 <<END > 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 > <VirtualHost 203.0.113.4> > DocumentRoot /var/www/html/vhost > ErrorLog logs/vhost.error > CustomLog logs/vhost.access combined > </VirtualHost> > END
# cat vhost.conf <VirtualHost 203.0.113.4> DocumentRoot /var/www/html/vhost ErrorLog logs/vhost.error CustomLog logs/vhost.access combined </VirtualHost>
Nesse exemplo ao invés do outro anterior, o conteúdo digitado foi redirecionado há um arquivo.
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
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
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
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: