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?

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


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
)

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;)


+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
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.