我尝试运行以下命令:
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 输入(可能还包括输出)以防止混乱。