Bash 将提示写入哪个流?

11 command-line bash prompt

我正在尝试将 bash 的所有输出(提示、用户输入、结果)重定向到一个文件

例子:

/bin/bash > file.txt 2>&1
Run Code Online (Sandbox Code Playgroud)

我认为这会奏效,但我没有收到提示。谁能告诉我我做错了什么?

seh*_*ehe 10

Bash 仅在交互模式下输出提示。即它通常输出到终端(Linux 上的 /dev/tty)。那既不是 /dev/stdout 也不是 /dev/stdin :)

现在,我不确定,但我可以想象,当没有功能齐全的 tty 时,bash 将允许有限的交互模式。在这种情况下,我希望将提示写入标准输出。我没有测试过。

很好的概念证明:

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

将只输出 1..10 就好像没有重定向一样。像提示一样,输出直接发送到终端(如果没有就会失败)

提示:如果您想收集所有内容,请查看

  • 这是不正确的。提示符将写入 stderr,即文件描述符 2,无论它是否是 TTY。这很容易验证:“bash -i > stdout.txt 2> stderr.txt”,您将看到提示符被写入 stderr.txt,而不是您的终端。 (2认同)

roz*_*acz 6

最简单的方法是

bash -i >/tmp/logfile 2>&1
Run Code Online (Sandbox Code Playgroud)

当您键入命令时,Bash 会将所有内容写入/tmp/logfile并继续执行命令,但终端中不会显示任何内容。您可以在退出终端会话时使其退出 - 通过按Ctrl+D或键入exit

请注意,如果您在没有重定向的情况下运行相同的操作stderr,则只会将问候消息记录到文件中,其余所有内容都将在当前终端中运行。因此,关于 bash 输出其提示符(以及所有以下命令)的流的问题的答案似乎是:stderr

哦,是的,该-i参数只是强制 bash 以交互模式运行。不要听那些人的话 - 你不需要任何魔术来做到这一点;)


jll*_*gre 5

提示符被写入 stderr,如 truss(此处在 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
Run Code Online (Sandbox Code Playgroud)