![为什么从 /dev/stdin 读取的命令在发送到后台时会获得状态“[1]+ Stopped”?](https://linux22.com/image/218630/%E4%B8%BA%E4%BB%80%E4%B9%88%E4%BB%8E%20%2Fdev%2Fstdin%20%E8%AF%BB%E5%8F%96%E7%9A%84%E5%91%BD%E4%BB%A4%E5%9C%A8%E5%8F%91%E9%80%81%E5%88%B0%E5%90%8E%E5%8F%B0%E6%97%B6%E4%BC%9A%E8%8E%B7%E5%BE%97%E7%8A%B6%E6%80%81%E2%80%9C%5B1%5D%2B%20Stopped%E2%80%9D%EF%BC%9F.png)
我尝试运行以下命令:
cat
base64 /dev/stdin
md5sum /dev/stdin
tail /dev/stdin
在所有情况下,当我这样做时:
^Z
$ bg
$ jobs
我得到的状态是:[1]+ Stopped
而不是[1]+ Running
.
但如果我从管道中读取,则该作业被视为正在运行:
mkfifo /tmp/fifo1
cat /tmp/fifo1
^Z
$ bg
$ jobs
# [1]+ Running tail /tmp/fifo1 &
为什么读取/dev/stdin
命令会被视为Stopped
发送到后台?
答案1
这是设计使然;这就是 POSIX 作业控制的设计方式。
在 POSIX 作业控制下,有一个 TTY 设备(“控制 TTY”)与多个作业(由放入进程组的进程表示)关联。一次一个进程组是前台进程组;其他是后台进程组。
当后台进程组中的进程尝试从控制终端读取数据时,它会收到信号SIGTTIN
并停止。
后台进程组也有可能SIGTTOU
在尝试时收到写到航站楼。有一个 TTY 标志控制是否强制执行此行为:即是否允许来自后台的写入。 (设置或清除该标志的命令接口是stty tostop
/ stty -tostop
)。
这样做的目的是,如果后台进程可以窃取您的 TTY 输入,那将是一个疯狂的混乱。您的击键将随机分布在后台进程中。 POSIX 作业控制不仅可以处理进程,还可以像交通警察一样处理 TTY 输入(可能还包括输出)以防止混乱。