Bash 本身的输出去了哪里?

Bash 本身的输出去了哪里?

对于一个脚本,我想重定向sleep 100&命令后出现在我的 shell 中的“[1] 00000”消息。我不再需要它了,但在解决这个问题时,我开始思考:Bash 本身的输出去了吗?为什么bash > testbash &> test或者bash | [some program]不起作用? 1 和 2 文件描述符只是会写入终端的文件描述符,对吧?那么,如果 bash 或任何其他程序想要打印给用户,它们如何绕过标准输出呢?

答案1

该消息只是发送到 stderr,但它是巴什的stderr,而不是命令的 stderr,因此重定向命令的输出和错误不会影响它。

为了说明这一点,您可以重定向命令组的 stderr 来重定向该消息:

$ { sleep 100& } 2>test
$ more test
[1] 94358
$ 
$ 
$ # Then, 100 seconds later:
[1]+  Done                    sleep 100
$ 

如果您不想要“完成”之类的状态消息(并且您处于通常显示它们的上下文中),您可以执行disown后台作业:

$ { sleep 10& disown $!; } 2>test
$ more test
[1] 94400
$ 
$ # After 10 seconds:
$ 

答案2

您与之交互的功能称为作业控制。它基于 POSIX 标准化的 API 函数。

作业控制是围绕终端会话进行组织的。作业控制 shell(在本例中为 Bash)是会话的“交通警察”。它控制哪些进程组位于作业控制前台,哪些进程组位于后台。当您使用>,<和等语法时,同一个 shell 还会安排所有间接寻址|。当 shell 想要将某些内容输出到终端时,它可以轻松地做到这一点,因为它是老板。

当某些命令在前台运行时,shell 会将其自身置于后台。在那些时刻,一切都很安静。 shell 在前台时会放置信息性消息。例如,当您向当前位于前台的程序发出Ctrl-时,您将看到如下消息:Z

[1]+  Stopped                 vi

在打印该消息之前,Bash 首先将该程序置于后台,并将其自身置于前台。然后它“握住 TTY 棒”:它可以从终端获取输入并写入终端。此时它会打印与作业控制相关的信息性消息。

重定向不会捕获来自 shell 本身的这些消息。当我们键入表明作业 1 正在后台运行并且具有 pid 的消息command > file &时,不会进入.那是没有意义的。 shell仅为此安排了重定向; shell 本身保存终端的文件描述符并向其发送消息。[1] nnnnnnnnnnfile> filecommand[1] ...

相关内容