如果 ctrl-c 中断通过 tail 发送到文件(其中 stderr/stdout 被重定向到)则进程停止

如果 ctrl-c 中断通过 tail 发送到文件(其中 stderr/stdout 被重定向到)则进程停止

我发现了 bash 中一些我以前从未遇到过的奇怪行为。

看来,如果我将 stderr 和 stdout 重定向到一个进程的文件,然后我 tail 该文件并向 tail 进程发送 ctrl-c 中断,那么原始进程就会停止!

例子:

$ ./ec2_backup.sh > backup.out 2>&1 &
$ tail -f backup.out
pending
Checking instance i-a3214dc7
running
Instance i-a3214dc7 is running.

^C
[1]+  Stopped                 ./ec2_backup.sh > backup.out 2>&1

环境是通过Mac通过ssh登录的Ubuntu 10.04 bash终端。

有人能向我解释一下吗?

谢谢!

答案1

我不认为尾部的CTRL+C是这里的问题。我敢打赌,作业在尾部运行时会停止,但您看不到它,因为 bash 直到向您显示 shell 提示符之前才会告诉您这些事情(此行为是默认行为,可以使用 进行更改set -b)。

我认为正在发生的事情是你的工作是使用 TTY 做一些事情。每当后台应用程序尝试从 TTY 读取时,它都会收到一个SIGTTIN。这是因为它在后台,不应该与用户交互,因此导致SIGTTIN进程被停止(不是被杀死,而是被停止)。此外,如果您已stty tostop设置并且应用程序尝试将任何输出写入 TTY,那么它也将被停止。
即使您重定向了 stdin 和 stdout,后台应用程序仍有可能找出它们所在的 TTY 并尝试直接访问它。

编辑(回答您的评论):
我在后台 ssh 上也遇到过类似的问题。我不知道它为什么尝试访问 TTY,但它确实访问了,并且因此收到了 SIGTTIN。

您可以尝试将您的命令包装在其中script

script -c ./ec2_backup.sh /dev/null &>/dev/null </dev/null &

脚本创建一个 TTY 供进程交互,并将此 TTY 重定向到 STDIN/STDOUT 或从 STDIN/STDOUT 重定向。现在,那些认为自己正在与完整 TTY 交互的应用程序实际上只与简单的 STDIN 和 STDOUT 管道交互。这样,您现在可以将 STDIN 和 STOUT 重定向到,/dev/null而后台应用程序将无法尝试获取 TTY(并SIGTTIN从尝试这样做中获取)。

答案2

使用

nohup ./ec2_backup.sh > backup.out 2>&1 &

相关内容