exemplo de saída do console que não é gravado na saída padrão

2

Parece que read não grava na saída padrão.

$ cat test.sh
#!/bin/bash
read -p "type a key and Enter" key
echo "the key was $key"
$ ./test.sh
type a key and Enterx
the key was x
$ ./test.sh | tee file
type a key and Enterx
the key was x
$ cat file
the key was x

Tentando sem um script ...

$ read -p "type a key and Enter" key | tee file
type a key and Enterx
$ cat file
$ 

O comando read é descrito aqui . Uma breve descrição: "Leia uma linha da entrada padrão".

Informações sobre o pipe, | , de O Linux Command Line (2ª Edição da Internet) , de William E. Shotts, segue .

  

Usando o operador de pipe "|" (barra vertical), a saída padrão de um   comando pode ser canalizado para a entrada padrão de outro:    command1 | command2

Na página man de tee está esta descrição:

  

leia a partir da entrada padrão e grave na saída e nos arquivos padrão

A página man do tee está neste link .

Onde está a lista de todos os outros exemplos de programas que gravam no console, mas na verdade não usam saída padrão ou, na ausência de tal lista, qual é a regra geral para saber quando um programa que grava no console não está usando saída padrão?

Parece que read viola o Princípio de menor espanto .

    
por H2ONaCl 07.01.2017 / 04:40

2 respostas

6

No seu exemplo, read está escrevendo para stderr em vez de stdout. Aqui está como eu sei:

$ read -p "Type a key and press Enter: " key >/dev/null
Type a key and press Enter: x
$ read -p "Type a key and press Enter: " key 2>/dev/null
x

Você pode fazer este teste em qualquer programa cuja saída você deseja redirecionar.

Então o comando que você está procurando é isto:

$ read -p "Type a key and press Enter: " key 2>&1 | tee file
Type a key and press Enter: x
$ cat file
Type a key and press Enter: $

Para explicações sobre os redirecionamentos acima:

por wjandrea 07.01.2017 / 05:10
2

Com o que wjandrea disse, é correto que você possa pegar o stderr que a leitura está fazendo. Infelizmente, tentar ler com stderr não mantém a variável key , portanto, a saída para echo $key terminará em branco. No entanto, em um script, ele manterá a variável porque a própria linha de leitura não está sendo redirecionada de stderr para stdout 2>&1 no script. Em vez disso, o script consegue manter a variável porque agora está definida antes de chegar ao redirecionamento. Acho que para facilitar, use echo lines. Eu adicionei todos os exemplos.

Exemplo do seu script:

:~$ cat test1.sh 
#!/bin/bash
read -p "type a key and Enter: " key
echo "the key was $key"

:~$ ./test1.sh | tee junk
type a key and Enter: G
the key was G

:~$ cat junk
the key was G

Com redirecionamento 2>&1 :

:~$ ./test1.sh 2>&1 | tee junk
type a key and Enter: G
the key was G

:~$ cat junk
type a key and Enter: the key was G

Com echo line:

:~$ cat test.sh 
#!/bin/bash
echo -n "Type a key and press Enter: "
read key
echo "the key was $key"

echo line com o comando tee:

:~$ ./test.sh | tee junk
Type a key and press Enter: X
the key was X

:~$ cat junk
Type a key and press Enter: the key was X

Exemplo do script não:

com stderr :

:~$ read -p "Type a key and press Enter: " key 2>&1 |tee junk; echo "The key was $key" | tee -a junk
Type a key and press Enter: F
The key was 

:~$ cat junk
Type a key and press Enter: The key was 

Com echo e vários comandos tee:

:~$ echo -n "Type a key and press Enter: " | tee junk; read key; echo "The key was $key" | tee -a junk
Type a key and press Enter: F
The key was F

:~$ cat junk
Type a key and press Enter: The key was F

Espero que isso ajude!

    
por Terrance 07.01.2017 / 09:25