В какой поток Bash пишет свое приглашение?

8

Я пытаюсь перенаправить весь вывод из bash (приглашение, ввод пользователя, результаты) в файл

Пример:

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

Я думал, что это сработает, но я не получаю подсказку. Может кто-нибудь сказать мне, что я делаю не так?

Жиль "ТАК - перестань быть злым"
источник

Ответы:

9

Bash выводит подсказку только в интерактивном режиме. Т.е. это нормально выводится на терминал (/ dev / tty на linux). Это не / dev / stdout или / dev / stdin :)

Теперь я не уверен, но могу представить, что bash разрешит ограниченный интерактивный режим, когда нет полностью функционального tty. В этом случае я ожидаю, что приглашение будет записано на стандартный вывод. Я не проверял это.

Хорошее доказательство концепции:

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

будет просто выводить 1..10, как если бы не было перенаправления. Как и подсказка, вывод напрямую отправляется на терминал (который не будет выполнен, если его нет)

СОВЕТ: если вы хотите, чтобы все было собрано, посмотрите на

sehe
источник
Добавлены подсказки о том, как потенциально получить больший вывод bash в трубу
sehe
seqявляется крайне нестандартной внешней командой, и ее не следует использовать таким образом. Если вы используете bash, сделайте что-то вроде for x in {1..10}или for ((x=1; x<=10; x++))вместо.
Крис Даун
@Chris: хорошая точка зрения, спасибо за хедз-ап
sehe
2

Чтобы обмануть себя, bashдумая, что это в интерактивном режиме (хотя stdoutи не отправляется на терминал), вы можете использовать уже упомянутую scriptкоманду.

(
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

Самый простой способ сделать это

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

Bash будет записывать все /tmp/logfileи продолжать выполнять команды по мере их ввода, но в терминале ничего не будет отображаться. Вы можете заставить его выйти так же, как вы выходите из сеанса терминала - нажав Ctrl+ Dили набрав exit.

Обратите внимание, что если вы выполните то же самое без stderrперенаправления, в файл будет записано только приветственное сообщение, а все остальное будет работать в вашем текущем терминале. Таким образом, ответ на ваш вопрос о потоке, на который bash выводит свою подсказку (и все следующие команды), выглядит следующим образом: stderr .

О да, и -iпараметр просто заставляет bash работать в интерактивном режиме. Не слушайте этих людей - вам не нужны никакие фокусы;)

rozcietrzewiacz
источник
+1 за использование <sub>для форматирования. Я только что узнал что-то новое сегодня. : D
Крис К
2

Подсказка пишется в stderr как ферма (здесь на Solaris):

$ 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
источник