redirecionamento stderr em subshell muda a saída de tput

4

Então, estou trabalhando em um script e descobri um comportamento estranho. Tenho certeza de que há uma explicação lógica porque a saída da linha de comando 4 th e 6 th é diferente dos outros casos, mas não consigo encontrá-la.

1 $ tput cols
128

2 $ tput cols 2>/dev/null
128

3 $ echo $(tput cols)
128

4 $ echo $(tput cols 2>/dev/null)
80

5 $ (tput cols >/tmp/cols.txt); cat /tmp/cols.txt
128

6 $ (tput cols &>/tmp/cols.txt); cat /tmp/cols.txt
80

7 $ echo $(tput cols 2>/dev/null; echo $COLUMNS; tput cols)
80 128 128

Por que o redirecionamento de stderr altera a saída de tput em uma subshell?

Por fim, quero fazer algo assim em meu script para fazê-lo funcionar em sistemas em que tput / ncurses não está disponível:

cols=$(tput cols 2>/dev/null || echo $COLUMNS)

O exemplo acima foi criado com o Bash 4.3.46 (1) -release e ncurses 6.0.20150627

    
por 816-8055 15.10.2016 / 10:22

1 resposta

2

De acordo com strace , isso acontece porque tput apenas tenta ler as configurações do stdout e stderr (fd 1 & 2). Como você redirecionou explicitamente o stderr e o $( ) também redireciona o stdout, o tput desiste.

A melhor solução seria remendar o tput para também verificar stdin para a presença de um tty; no entanto, você também pode remover apenas o 2>/dev/null redirect, já que tput cols nunca exibe nenhuma mensagem de erro. (E se ele gerou algumas mensagens de erro, é melhor prestar atenção nelas.)

    
por 15.10.2016 / 12:33