为什么在 bash 中启动的后台进程会将标准输出打印到屏幕上?

为什么在 bash 中启动的后台进程会将标准输出打印到屏幕上?

我很难理解我的情况,而且谷歌到目前为止也没有提供太多帮助。

我启动了 bash 后台作业:

ping google.com &

首先我获取进程 ID,然后 Bash 将标准输出打印到屏幕上。

user@host:~$ ping google.com &
[1] 14004
user@host:~$ PING google.com (173.194.44.66) 56(84) bytes of data.
64 bytes from ham02s14-in-f2.1e100.net (173.194.44.66): icmp_seq=1 ttl=54 time=26.3 ms
64 bytes from ham02s14-in-f2.1e100.net (173.194.44.66): icmp_seq=2 ttl=54 time=27.4 ms
64 bytes from ham02s14-in-f2.1e100.net (173.194.44.66): icmp_seq=3 ttl=54 time=29.2 ms
...

这与我今天读到的所有内容相矛盾。我有一个标准的 Debian Jessie 设置,运行 GNU bash,版本 4.3.30(1)-release (x86_64-pc-linux-gnu)。

有人能向我解释一下吗?谢谢。

答案1

默认情况下,至少对于符合 POSIX 标准的系统,在后台运行命令,&只会分离stdin,因此您将能够运行其他命令。stdout并且stderr仍然连接到父 shell。

如果您不想看到stdout和/或stderr您可以将它们重定向到文件或/dev/null

command &>log.txt &                #stdout and stderr to log.txt
command 1>/dev/null &               #stdout to /dev/null, stderr still attached to shell
command 1>output.log 2>error.log &  #stdout to output.log, stderr to error.log

答案2

后台进程的标准输出是否显示在终端上由您决定。您可以使用stty实用程序更改行为。

例子

默认允许后台进程写入终端:

$ echo Hello &
[1] 25850
Hello
$

可以使用以下命令更改该行为stty

$ stty tostop
$ echo Hello &
[2] 25873

[2]+  Stopped                 echo Hello
$ 

指定后tostop,后台进程在尝试写入 stdout 时会停止。如果要允许它继续,可以将其带回前台:

$ fg
echo Hello
Hello
$

要切换回来,请运行stty -tostop。运行后,新的创建的后台作业将被允许写入标准输出。(现有作业不会受到影响。)

文档

man stty该选项解释tostop如下:

* [-]tostop
停止尝试写入终端的后台作业

手册页使用上面的前导*来标识此选项为非 POSIX。

相关内容