Restaurando a saída no terminal depois de emitir "exec &> filename"


15

Estou tentando executar o seguinte:

exec &>filename

Depois disso, não consigo ver nada, inclusive o que eu digitei, tudo bem.

Eu tento freneticamente exec 1>&1e exec 2>&2, mas nada acontece.

Agora, sem matar o shell, como recupero a saída redirecionada para o stdout e o erro redirecionado para o stderr, respectivamente? Os descritores de arquivo são a única maneira de referenciar o padrão [in | out] put and stderr?


1
Hmm ... por que você redireciona o stderr / stdout do seu shell interativo então? Essa execconstrução é geralmente usada em scripts que são executados em um subshell, para redirecionar sua saída, por exemplo, para um arquivo. Não vejo utilidade em uma sessão interativa.
Martin von Wittich

3
@MartinvonWittich Concordo com a declaração do exec. Concordo. Eu sou apenas uma criança brincando :)
user917279 23/09

Respostas:


23

Depois de executar exec &>filename, a saída padrão e o erro padrão do shell vão para filename. A entrada padrão é o descritor de arquivo 0 por definição, e a saída padrão é fd 1 e o erro padrão é fd 2.

Um descritor de arquivo não é redirecionado ou não redirecionado: ele sempre vai para algum lugar (supondo que o processo tenha esse descritor aberto). Redirecionar um descritor de arquivo significa mudar para onde ele vai. Quando você executou exec &>filename, o stdout e o stderr estavam anteriormente conectados ao terminal e se conectaram ao filename.

Há sempre uma maneira de se referir ao terminal atual: /dev/tty. Quando um processo abre esse arquivo, sempre significa o terminal de controle do processo , qualquer que seja. Portanto, se você quiser recuperar o stdout e o stderr originais desse shell, poderá fazê-lo porque o arquivo ao qual eles estavam conectados ainda está por aí.

exec &>/dev/tty

1
como @Joseph R. respondeu $ (tty) me mostra / dev / pty0, mas seu comando também funciona, qual é mais portátil entre os tipos de Unix? obrigado pela resposta mais clara.
user917279

2
@ user917279 Eles são igualmente portáteis no sentido de trabalhar em diferentes tipos de unix. /dev/ttyfunciona em casos em $(tty)que não:/dev/tty funciona desde que o processo tenha um terminal de controle (o melhor que você pode esperar, pois ainda há algo que ainda está conectando o processo ao terminal), enquanto $(tty)exige que o terminal ainda esteja aberto na entrada padrão.
Gilles 'SO- stop be evil'

11

Você quer

exec &>$(tty)

O que você está fazendo na sua pergunta é replicar no stdout e stderr o stdout e o stderr originais que já foram redirecionados para o arquivo.

Como a resposta de Gilles explica, ttyretornará o dispositivo terminal do terminal atual. É aqui que os três descritores de arquivo padrão vêm / vão por padrão em um shell de login. Portanto, a instrução acima utiliza ttypara redirecionar stdout e stderr de volta ao dispositivo terminal como eram antes.

Se você está preocupado com a portabilidade (conforme seu comentário na resposta de Gilles), ambos os métodos (o utilitário tty e o /dev/ttyarquivo ) estão no padrão POSIX.

Texto copiado literalmente do comentário de Gilles:

There's an advantage to /dev/tty: it works even after exec <somefile, 
whereas $(tty) would complain “not a tty”

funciona! Obrigado. echo $ (tty) fornece / dev / pty0 (no cygwin), como isso está relacionado ao stdin, stdout e o que acontece com a instrução acima? informe-me se precisar fazer isso como uma pergunta separada.
user917279

@ user917279 Resposta atualizada.
Joseph R.

Obrigado Joseph. Postei essa pergunta antes de analisar a resposta de Giles. Muito obrigado. Permita-me marcar a resposta de Giles como aceita, pois fez com que até mentes idiotas como a minha entendessem corretamente.
user917279

2
Há uma vantagem em /dev/tty: funciona mesmo depois exec <somefile, enquanto $(tty)queixaria-se "não é um tty".
Gilles 'SO- stop be evil'

@Gilles Obrigado pelo comentário caracteristicamente esclarecedora :)
Joseph R.
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.