我在 Ubuntu 中使用 Linux 终端。
当我编写seq 100 1 | less &
在后台运行它时,它就停止了。
我也使用其他方法在后台运行它,例如使用,bg [jobnr]
但它就停止了。
我找到作业编号并写入bg 1
(当它为 1 时),但随后我检查进程,发现它没有运行。
同样的情况man pi
也发生在其他“手册页”上。
但pi 10000000
可以在后台运行,当它完成时,它只是在终端上打印 pi 号。
这是一个作业,看看是否less
可以在后台运行,以及为什么它不能在后台运行。在网上搜索后,我没有找到太多关于原因的信息。
为什么有些进程无法在后台运行,但其他进程却可以运行,尽管两者都在终端上打印?
答案1
less
无法在后台运行,因为它正在尝试与控制终端交互,这会导致它被强制停止。只有前台进程可以从终端读取数据或更改终端设置。
当后台进程尝试更改终端设置时,它会收到SIGTTOU
信号。当它尝试从终端读取数据时,它会收到一个SIGTTIN
信号。两个信号都会使其停止。如果进程继续运行并忽略这些信号,则导致它们的操作可能会失败,因此这不是解决此问题的方法(例如,从终端读取将失败并出现错误EIO
)。
笔记:
less
其独特之处在于,为了能够用作command | less
,它直接通过 打开控制终端,/dev/tty
而不是像大多数编辑器或 shell 等其他交互式程序那样假设控制终端是其 stdin 或 stderr。
您可以配置您的终端,stty tostop
以便后台程序尝试写到控制终端的操作也会被停止,但这不是任何地方的默认设置,而且不太实用。
答案2
因为它需要访问终端。
如果进程在后台运行,则所有终端输入都将发送到在前台运行的进程,很可能是 shell。如果后台进程在需要读取时就选择一个字符,那么就会干扰您正常的前台工作。要了解这可能会导致什么结果,请考虑如果您的后台进程只能读取中间的终端会发生什么。
Process1: important data(bg) you type Process2: just a quiz-game (fg)
output output
Do you want to quit(q) or How do you call a group of 5
continue (c) music players?
<- q
OK, quit, save data? u ->
i ->
<- n
t ->
Ok destroyed all data. e ->
t ->
<enter>-> Wrong answer: uitet.
您可以使用以下脚本作为示例来了解其工作原理:
#!/bin/bash
while read sentence ; do
echo "$sentence"
echo '----------------'
head -1 /dev/tty
done
正常read
从 STDIN 读取输入。您可以将任何内容重定向到它。这head -1 /dev/tty
将强制从终端输入。如果您在前台运行,脚本将为您提供的每个输入提供一行。
如果您在后台运行此脚本,cat tst.sh | bash tst.sh &
它将停止在您明确需要从终端输入的位置。