Em qual fluxo o Bash escreve seu prompt?

7

Estou tentando redirecionar todas as saídas do bash (prompt, entrada do usuário, resultados) para um arquivo

Exemplo:

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

Eu achei que funcionaria, mas não estou recebendo o prompt. Alguém pode me dizer o que estou fazendo errado?

    
por Gilles 15.09.2011 / 15:28

4 respostas

9

O Bash exibe 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, esperaria que o prompt fosse gravado no stdout. Eu não testei isso.

Boa prova de conceito:

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

apenas mostrará 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ê quisesse que tudo fosse coletado, olhe para

por 15.09.2011 / 16:25
2

Para enganar bash ao pensar que está no modo interativo (embora stdout não esteja sendo enviado para um terminal), você pode usar o comando script 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
)
    
por 15.09.2011 / 17:01
2

O prompt é gravado em stderr, já que o truss (no Solaris aqui) mostra:

$ 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
    
por 17.09.2011 / 08:25
1

A maneira mais simples de fazer isso seria

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

O Bash escreve tudo em /tmp/logfile e continua executando os comandos conforme você os digita, mas nada será exibido no terminal. Você pode fazê-lo sair assim que sair da sua sessão de terminal - pressionando Ctrl + D ou digitando exit .

Observe que, se você executar a mesma coisa sem o redirecionamento stderr , só terá a mensagem de saudação registrada no arquivo, e o restante funcionará no terminal atual. Portanto, a resposta à sua pergunta sobre o fluxo no qual o bash exibe seu prompt (e todos os comandos a seguir) parece ser: stderr .

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

    
por 16.09.2011 / 10:54