Como exportar para o redirecionamento de substituição de tela

7

É possível, dentro de um script de shell, escrever na tela enquanto STDOUT e STDERR estão sendo redirecionados?

Eu tenho um script de shell que quero capturar STDOUT e STDERR. O script será executado por talvez uma hora ou mais, então, ocasionalmente, quero escrever algumas mensagens de status na tela que será exibida e não redirecionada (não capturada).

Para um exemplo mínimo, eu tenho um script de shell, digamos "./myscript.sh":

#!/bin/sh -u

echo "Message A: This writes to STDOUT or wherever '1>' redirects to."
echo "Message B: This writes to STDOUT or wherever '1>' redirects to.">&1
echo "Message C: This writes to STDERR or wherever '2>' redirects to.">/dev/stderr
echo "Message D: This writes to STDERR or wherever '2>' redirects to.">&2
echo "Message E: Write this to 'screen' regardless of (overriding) redirection." #>???  


Então, por exemplo, eu gostaria de ver esta saída quando eu executo o script assim:

[~]# ./myscript.sh > fileout 2> filerr
Message E: Write this to 'screen' regardless of (overriding) redirection.
[~]# ./myscript.sh > /dev/null 2>&1
Message E: Write this to 'screen' regardless of (overriding) redirection.
[~]#    


Se isso não puder ser feito "diretamente", é possível interromper temporariamente o redirecionamento, imprimir algo na tela e restaurar o redirecionamento como estava?

Algumas informações sobre o computador:

[~]# uname -srvmpio
Linux 3.2.45 #4 SMP Wed May 15 19:43:53 CDT 2013 x86_64 x86_64 x86_64 GNU/Linux

[~]# ls -l /bin/sh /dev/stdout /dev/stderr
lrwxrwxrwx 1 root root  4 Jul 18 23:18 /bin/sh -> bash
lrwxrwxrwx 1 root root 15 Jun 29  2013 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root 15 Jun 29  2013 /dev/stdout -> /proc/self/fd/1
    
por Kevin Fegan 04.01.2014 / 19:26

3 respostas

4

Tente um script como este:

#!/bin/bash
echo "to fd1" >&1
echo "to fd2" >&2
echo "to screen" >$(tty)

Quando você liga, parece assim:

user@host:~# ./script
to fd1
to fd2
to screen
user@host:~# ./script 1>/dev/null
to fd2
to screen
user@host:~# ./script 2>/dev/null
to fd1
to screen
user@host:~# ./script > /dev/null 2>&1
to screen
    
por 04.01.2014 / 23:18
2

Eu não sei sobre todo o redirecionamento tty, mas é isso que eu faço:

Na verdade, não redirecione, mas envie a saída desejada como um parâmetro ou, se você estiver redirecionando no próprio script, poderá alternar o redirecionamento a qualquer momento executando:

exec 2> /some/new/destination 1> /some/other/destination

mas você pode querer salvar os antigos ...

exec  3>&1 4>&2 2> /some/new/destination 1> /some/other/destination

dessa forma você pode voltar a ele ... quando terminar, ou quiser escrever na tela

escreva para a tela: echo "message" 1>&3

ou ..

tudo pronto: exec 1>&3 2>&4 # tudo volta ao normal:)

    
por 08.10.2014 / 20:23
0

Usando o exemplo da resposta por caos :

echo "to screen" >$(tty)

não funcionou para mim. Recebo um erro ao tentar usá-lo:

./myscript.sh: line xx: /dev/pts/3: Permission denied

Eu criei uma solução para usar outro descritor de arquivos (9). Aqui está "./myscript.sh":

#!/bin/sh -u

## This is placed one time at the top of the script  
## to detect if file descriptor (9) is available for writing.
if [ ! -t 3 ]; then
    echo "Error, file descriptor (9) not open on terminal." >&2
    echo "" >&2
    if [ ! -t 2 ]; then
        echo "Error, file descriptor (9) not open on terminal."
        echo ""
    fi
    exit 1
fi

echo "Message A: This writes to stdout or wherever '1>' redirects to."
echo "Message B: This writes to stdout or wherever '1>' redirects to.">&1
echo "Message C: This writes to stderr or wherever '2>' redirects to.">/dev/stderr
echo "Message D: This writes to stderr or wherever '2>' redirects to.">&2
echo "Message E: Write this to 'screen' regardless of '1>/2>' redirection." >&9
echo " " >&9

Eu usei o descritor de arquivo 9 para enviar as mensagens de "status", mas outros descritores de arquivos válidos devem funcionar.

Para usá-lo, ao chamar o script, você deve incluir o redirecionamento do descritor de arquivo (9) para STDOUT (9 > & 1) como o primeiro redirecionamento.

Aqui está a saída quando eu chamo "./myscript.sh":

[~]# ./myscript.sh
[~]# ./myscript.sh >/dev/null
[~]# ./myscript.sh 2>/dev/null
Error, file descriptor (9) not open on terminal.

[~]# ./myscript.sh >/dev/null 9>&1
Error, file descriptor (9) not open on terminal.

[~]# ./myscript.sh 9>&1 >/dev/null
Message C: This writes to stderr or wherever '2>' redirects to.
Message D: This writes to stderr or wherever '2>' redirects to.
Message E: Write this to 'screen' regardless of '1>/2>' redirection.

[~]# ./myscript.sh 9>&1 2>/dev/null
Message A: This writes to stdout or wherever '1>' redirects to.
Message B: This writes to stdout or wherever '1>' redirects to.
Message E: Write this to 'screen' regardless of '1>/2>' redirection.

[~]# ./myscript.sh 9>&1 >/dev/null 2>&1
[~]# ./myscript.sh 9>&1 &>/dev/null
[~]# ./myscript.sh 9>&1 >&/dev/null
Message E: Write this to 'screen' regardless of '1>/2>' redirection.

[~]#
    
por 06.01.2014 / 15:28