Em qual fluxo o Bash grava seu prompt?

8

Estou tentando redirecionar toda a saída do bash (prompt, entrada do usuário, resultados) para um arquivo

Exemplo:

/bin/bash > file.txt 2>&1

Eu pensei que iria funcionar, mas não estou recebendo o prompt. Alguém pode me dizer o que estou fazendo de errado?

Gilles 'SO- parar de ser mau'
fonte

Respostas:

9

O Bash envia o prompt apenas no modo interativo. Ou seja, é normalmente enviado para o terminal (/ dev / tty no linux). Isso não é / dev / stdout ou / dev / stdin :)

Agora, não tenho certeza, mas posso imaginar que o bash permitirá o modo interativo limitado quando não houver um tty totalmente funcional. Nesse caso, eu esperaria que o prompt fosse gravado em stdout. Eu não testei isso.

Prova agradável de conceito:

(for a in some set of words; do echo $a > /dev/tty; done) 2>&1 > /dev/null

irá apenas gerar 1..10 como se não houvesse redirecionamento. Como o prompt, a saída é enviada diretamente para o terminal (que falhará se não houver um)

DICA: se você quiser que tudo seja coletado, olhe

ver
fonte
Adicionadas dicas sobre como potencialmente obter mais saída do bash em um pipe
veja se
seqé um comando externo altamente fora do padrão e não deve ser usado dessa maneira. Se você estiver usando bash, faça algo parecido for x in {1..10}ou, em for ((x=1; x<=10; x++))vez disso.
Chris Baixo
@ Chris: bom ponto, graças a cabeça para cima
sehe
2

Para enganar basha pensar que está no modo interativo (embora stdoutnão esteja sendo enviado para um terminal), você pode usar o scriptcomando já mencionado .

(
exec 1> >(tee bashlog.txt) 2>&1
script -q /dev/null /bin/bash -l
)

# alternative without script command
(
# bash: no job control in this shell
exec 1> >(tee bashlog.txt) 2>&1
/bin/bash -il
)

fonte
2

A maneira mais simples de fazer isso seria

bash -i >/tmp/logfile 2>&1

O Bash gravará tudo /tmp/logfilee continuará executando os comandos enquanto você os digita, mas nada será exibido no terminal. Você pode fazê-lo sair da mesma maneira que sai da sessão do terminal - pressionando Ctrl+ Dou digitando exit.

Observe que, se você executar a mesma coisa sem stderrredirecionar, terá apenas a mensagem de saudação registrada no arquivo, todo o resto funcionará no seu terminal atual. Portanto, a resposta à sua pergunta sobre o fluxo para o qual o bash gera seu prompt (e todos os seguintes comandos) parece ser: stderr .

Ah, sim, e o -iparâmetro simplesmente força o bash a executar no modo interativo. Não dê ouvidos a essas pessoas - você não precisa de nenhum truque de mágica para fazer isso;)

rozcietrzewiacz
fonte
+1 para usar <sub>para formatar. Acabei de aprender algo novo hoje. : D
Chris K
2

O prompt é gravado no stderr como mostra a treliça (no Solaris aqui):

$ truss -ft write -p 10501
10501:  write(2, " d", 1)               = 1
10501:  write(2, " a", 1)               = 1
10501:  write(2, " t", 1)               = 1
10501:  write(2, " e", 1)               = 1
10501:  write(2, "\n", 1)               = 1
10521:  write(1, " S a t u r d a y ,   S e".., 46)  = 46
10501:      Received signal #18, SIGCLD [caught]
10501:        siginfo: SIGCLD CLD_EXITED pid=10521 status=0x0000
10501:  write(2, " $  ", 2)             = 2
jlliagre
fonte