为什么从 /dev/stdin 读取的命令在发送到后台时会获得状态“[1]+ Stopped”?

为什么从 /dev/stdin 读取的命令在发送到后台时会获得状态“[1]+ Stopped”?

我尝试运行以下命令:

  • 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 输入(可能还包括输出)以防止混乱。

相关内容