redireciona temporariamente STDOUT para outro descritor de arquivo, mas ainda para a tela

2

Estou fazendo um script que executa alguns comandos, e esses comandos mostram alguma saída em STDOUT (e STDERR também, mas isso não é problema). Eu preciso que meu script gere um arquivo .tar.gz para STDOUT , então a saída de alguns comandos executados no script também vai para STDOUT e isso termina com um arquivo .tar.gz não válido na saída. / p>

Então, em suma, é possível enviar os primeiros comandos para a tela (como eu ainda quero ver a saída), mas não via STDOUT ? Também gostaria de manter o STDERR intocado para que apenas mensagens de erro apareçam lá.

Um exemplo simples do que quero dizer. Este seria meu script:

#!/bin/bash

# the output of these commands shouldn't go to STDOUT, but still appear on screen
some_cmd foo bar
other_cmd baz

#the following command creates a tar.gz of the "whatever" folder,
#and outputs the result to STDOUT
tar zc whatever/

Eu tentei mexer com exec e os descritores de arquivo, mas ainda não consigo trabalhar:

#!/bin/bash

# save STDOUT to #3
exec 3>&1

# the output of these commands should go to #3 and screen, but not STDOUT
some_cmd foo bar
other_cmd baz

# restore STDOUT
exec 1>&3

# the output of this command should be the only one that goes to STDOUT
tar zc whatever/

Eu acho que estou faltando fechar STDOUT após o primeiro exec e reabri-lo novamente ou algo assim, mas não consigo encontrar o caminho certo para fazê-lo (agora o resultado é o mesmo como se eu não fizesse adicione o exec s

    
por Carlos Campderrós 16.04.2012 / 11:20

3 respostas

5

stdout é a tela. Não há separação entre stdout e "a tela".

Neste caso, eu apenas redirecionaria o stdout para o stderr temporariamente com 1>&2 dentro de um subshell. Isso fará com que a saída dos comandos seja mostrada na tela, mas não estará no fluxo stdout do programa.

#!/bin/bash

# the output of these commands shouldn't go to STDOUT, but still appear on screen

# Start a subshell
(
    1>&2                # Redirect stdout to stderr
    some_cmd foo bar
    other_cmd baz
)
# At the end of the subshell, the file descriptors are 
# as they usually are (no redirection) as the subshell has exited.

#the following command creates a tar.gz of the "whatever" folder,
#and outputs the result to STDOUT
tar zc whatever/

Existe uma razão pela qual você precisa canalizar a saída desse script para outra coisa? Normalmente, você só teria que escrever em um arquivo usando o sinal -f ou executar um redirecionamento apenas no comando tar: tar zc whatever > filename.tar.gz (a menos que você estivesse colocando-o em um dispositivo, como uma fita ou usando-o como uma forma de cópia).

    
por 16.04.2012 / 12:01
1

Não seria muito mais fácil usar a opção -f no comando tar para informar ao tar para gravar em um arquivo?

tar zcf whatever.tar.gz whatever/

Se isso não fizer o que você quer, então você terá que redirecionar individualmente cada comando que pode escrever para STDOUT

some_cmd foo bar 1>&2
    
por 16.04.2012 / 12:17
0

Acho que você está procurando algum tipo de multiplexação.

Este é um exemplo simples de como acrescentar registro de data e hora a cada linha de saída padrão: link

Você pode usar alguma tag especial em vez de timestamp para marcar linhas de log. Do que você teria que remover essas linhas do outro lado. Então, o uso seria assim:

ssh user@remoteserver the_script.sh | create_tar.sh filename

create_tar.sh deve ser um script que imprime linhas com tag de log e redireciona outras linhas para o arquivo.

    
por 16.04.2012 / 12:58