CI066 - Oficina de Programação
Notas de Aula # 05
2º semestre 2003

Prof. Armando Luiz N. Delgado

1 Entrada e Saída Padrão em UNIX

Referência básica: Capítulo 5, seção 5.5 da Apostila Linux Básico (1)

Entrada:
dados que são passados a um programa, seja via teclado de um terminal, seja pela leitura de um arquivo em disco;
Entrada Padrão:
Teclado. Também denominado Standard Input ou STDIN.
Saída:
mensagens que são geradas por um programa como resultado do processamento associado que são e disponibilizadas ao usuário, geralmente via terminal;
Saída Padrão:
Tela do terminal de onde o programa foi iniciado. Também denominado Standard Output ou STDOUT.
Saída de Erros:
mensagens indicativas de erros ou avisos que são geradas por um programa e disponibilizadas ao usuário, geralmente via terminal;
Saída Padrão de Erros:
Tela do terminal de onde o programa foi iniciado. Também denominado Standard Error Output ou STDERR.

2 Redirecionamento de Entrada e Saída Padrão em UNIX

Forma de desviar o local de onde um programa lê ou escreve informações:

Entrada Padrão:
redireciona-se com o caracter  < 
Saída Padrão:
redireciona-se com o caracter  > 
Saída Padrão de Erros:
redireciona-se com  2> 

Exemplos:

ci066@dupond:~cat ~/yes.rsp
y
ci066@dupond:~rm -i ~ci066/texto  < ~/yes.rsp
rm: remove 'no'?
ci066@dupond:~ 
ci066@dupond:~ls -lR ~ci066/LabNum4  > ~/LabNum4.txt
ci066@dupond:~find /home/grad/*02 -print  > ~/files.txt  2> ~/erros.txt

O redirecionamento é destrutivo, isto é, ele apaga o conteúdo anterior do arquivo para onde será redirecionada a saída.

É possível redirecionamento NÃO-DESTRUTIVO. Usa-se a notação  »  no lugar de  >  e implica em ACRESCENTAR a saída ao FINAL do arquivo para onde está sendo feito o redirecionamento.

Exemplos:

ci066@dupond:~ls -lR ~ci066/LabNum4  > ~/Arquivos.txt
ci066@dupond:~find ~ci066 -print  » ~/Arquivos.txt  2> /dev/null

Quando o usuário deseja que a saída padrão ou a saída de erros NÃO sejam exibidas na tela do terminal e tampouco sejam redirecionadas para um arquivo adicional, usa-se o redirecionamento para um arquivo especial: /dev/null. No exemplo acima, as mensagens de erro do comando find não serão exibidas, pois foram redirecionadas para /dev/null.

2.1 Bloqueio de redirecionamento destrutivo de saída

Da mesma forma que executar rm(1) sem a opção -i requer atenção para não ser surpreendido pelo destino cruel, fazer redirecionamento destrutivo de saída ( > e  2> ) também pode trazer surpresas desagradáveis.

Existe, felizmente, uma forma de bloquear o efeito destrutivo dos redirecionamentos de saída. Para isto define-se a opção noclobber do shell executando-se o comando abaixo:

                  set  -o  noclobber

Uma vez executado o comando acima, ao se tentar redirecionar STDOUT para um arquivo existente, uma mensagem de erro será exibida: ci066@dupond:~cat fantomas  > new_fantomas
ci066@dupond:~set -o noclobber
ci066@dupond:~cat nacional_kid  > new_fantomas
bash: new_fantomas: cannot overwrite existing file
ci066@dupond:~cat nacional_kid  >| new_fantomas
ci066@dupond:~

Para que os redirecionamentos de saída  > e  2>  voltem a ter seu comportamento destrutivo, existem duas soluções:

3 Pipeline

Suponha o seguinte exemplo:

ci066@dupond:~sort ~/Arquivos.txt  > ~/ordenados.txt
ci066@dupond:~less ~/ordenados.txt

Pipe é uma forma de redirecionamento que ``conecta'' a saída padrão de um programa à entrada padrão de outro programa. Com pipes (símbolo  | ) o exemplo acima se transforma em:

ci066@dupond:~sort ~/Arquivos.txt  | less

Pipelines podem ser usados em qualquer quantidade me uma linha de comando:

ci066@dupond:~ls -lR ~  | sort -r  | cut -c1-10  | less
...
ci066@dupond:~

Pipelines e Redirecionamentos podem ser usados em uma mesma linha de comando:

ci066@dupond:~find /var -print 2>/dev/null  | sort >~/LOG
ci066@dupond:~

No exemplo acima, a saída de erros (STDERR) do find(1) é redirecionada para /dev/null (isto é, não aparecerá na tela), mas a saída padrão (STDOUT) será redirecionada para o pipe. O comando sort(1) ordena o resultado do find(1) e redireciona o resultado final para o arquivo ~/LOG.

4 Inserindo a saída padrão em uma linha de comando

Observe os comandos abaixo:

ci066@dupond:~LAB_DIR=$HOME/LabNum5
ci066@dupond:~echo $LAB_DIR
/home/especial/ci066/LabNum5
ci066@dupond:~find $LAB_DIR -name ´*-8´ -exec rm -i {} $\backslash$;
....
ci066@dupond:~

Temos acima exemplos da expansão do valor de variáveis de ambiente em diversas linha de comando. No caso, usa-se o caracter $ para acessar e expandir o valor da variável onde isto for necessário.

Suponha agora o exemplo abaixo:

ci066@dupond:~find ~ci066 -type d -perm -111 -print
/home/especial/ci066/LabNum3/doc
/home/especial/ci066/LabNum4/lib
/home/especial/ci066/LabNum5
ci066@dupond:~find ~ci066/LabNum3/doc ~ci066/LabNum4 ~ci066/LabNum5 -exec chmod go-rwx {} $\backslash$;
ci066@dupond:~

Neste exemplo, deseja-se obter os diretórios que tenham permissão de navegação para todos os usuários e, nestes diretórios (e sub-árvores), retirar as permissões de Leitura, Escrita e Execução de todos os arquivos. Observe-se que a solução teve que ser feita em dois passos ou duas linhas de comando distintas, sendo que o usuário no caso do segundo comando teve de digitar todos os diretórios que o primeiro devolveu como resultado.

Existe uma forma de ``redirecionar'' a saída padrão de um comando para ser inserida em algum ponto de uma linha de comando. Para isto usa-se a crase (`) como no exemplo abaixo:

ci066@dupond:~DIRS=`find ~ci066 -type d -perm -111 -print`
ci066@dupond:~find $DIRS -exec chmod go-rwx {} $\backslash$;
ci066@dupond:~

Ao executar a primeira linha de comando acima, o shell ``redirecionou'' a saída padrão de find(1) e colocou como valor da variável shell DIRS. O valor desta foi, então, usado na execução da segunda linha de comando.

O exemplo acima poderia ser feito em apenas uma linha de comando:

ci066@dupond:~find `find ~ci066 -type d -perm -111 -print` -exec chmod go-rwx {} $\backslash$;
ci066@dupond:~

Em particular, bash(1) define a notação $(comando) como alternativa ao uso de crase. Assim, se o seu shell é bash(1), o exemplo acima pode ser executado na forma abaixo:

ci066@dupond:~find $(find ~ci066 -type d -perm -111 -print) -exec chmod go-rwx {} $\backslash$;
ci066@dupond:~

Bibliografia

1
PET Informática.
Linux Básico.
UFPR, Outubro 2002.
URL http://pet.inf.ufpr.br/ daniel/LinuxBasico.pdf.



Armando Luiz Nicolini Delgado 2003-10-20