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

Kat*_*ger 11 linux bash debian-jessie

我在理解我的情况时遇到了困难,到目前为止,谷歌并不是很有帮助。

我开始了一个 bash 后台工作:

ping google.com &
Run Code Online (Sandbox Code Playgroud)

首先我得到进程 ID,然后 Bash 将 stdout 打印到屏幕上。

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
...
Run Code Online (Sandbox Code Playgroud)

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

任何人都可以向我解释这一点吗?谢谢。

pet*_*try 16

默认情况下,至少对于 POSIX 兼容系统,在后台运行命令,使用&,仅 detaches stdin,因此您将能够运行其他命令。stdout并且stderr仍然附加到父壳。

如果您不想看到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
Run Code Online (Sandbox Code Playgroud)


Joh*_*024 7

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

例子

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

$ echo Hello &
[1] 25850
Hello
$
Run Code Online (Sandbox Code Playgroud)

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

$ stty tostop
$ echo Hello &
[2] 25873

[2]+  Stopped                 echo Hello
$ 
Run Code Online (Sandbox Code Playgroud)

有了tostop规定,后台进程,当它试图写入stdout停止。如果你想让它继续,你可以把它带回前台:

$ fg
echo Hello
Hello
$
Run Code Online (Sandbox Code Playgroud)

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

文档

man sttytostop选项解释如下:

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

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