为什么 shell 会忽略后台进程中的 SIGINT 和 SIGQUIT? [英] Why do shells ignore SIGINT and SIGQUIT in backgrounded processes?

查看:27
本文介绍了为什么 shell 会忽略后台进程中的 SIGINT 和 SIGQUIT?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我在脚本或 -c 片段中后台进程,后台进程将忽略 SIGINT 和 SIGQUIT:

If I background a processes in a script or a -c snippet, the backgrounded processes ignores SIGINT and SIGQUIT:

示例:

$ alias ps='ps -o pid,ppid,pgrp,sid,stat,tty,ignored,blocked,caught,wchan,min_flt,pmem,args --forest'
$ sh -c 'sleep 1000 & sleep 1000 | sleep 1000' & 
  sleep 0.01; ps |grep -v -e ps -e grep 
  PID  PPID  PGRP   SID STAT TT                IGNORED          BLOCKED           CAUGHT WCHAN   MINFL %MEM COMMAND
 6197  2143  6197  6197 Ss   pts/28   0000000000380004 0000000000010000 000000004b817efb wait    10039  0.0 -bash
 7593  6197  7593  6197 S    pts/28   0000000000000000 0000000000000000 0000000000010002 wait      148  0.0  \_ sh -c sleep 1000 & sleep 1000 | sleep 1000
 7595  7593  7593  6197 S    pts/28   0000000000000006 0000000000000000 0000000000000000 hrtime     85  0.0  |   \_ sleep 1000
 7596  7593  7593  6197 S    pts/28   0000000000000000 0000000000000000 0000000000000000 hrtime     85  0.0  |   \_ sleep 1000
 7597  7593  7593  6197 S    pts/28   0000000000000000 0000000000000000 0000000000000000 hrtime     85  0.0  |   \_ sleep 1000

这意味着如果我从交互式父 shell 运行 kill -INT -$!(或 fg 后跟 Ctrl-C)(bash),以 -c 片段为背景的 sleep 进程未到达并继续存在.

This means that if I run kill -INT -$! (or fg followed by Ctrl-C) from the interactive parent shell (bash), the sleep processes backgrounded from the -c snippet isn't reached and survives.

  PID  PPID  PGRP   SID STAT TT                IGNORED          BLOCKED           CAUGHT WCHAN   MINFL %MEM COMMAND
 6197  2143  6197  6197 Ss   pts/28   0000000000380004 0000000000010000 000000004b817efb wait    10103  0.0 -bash
 7595     1  7593  6197 S    pts/28   0000000000000006 0000000000000000 0000000000000000 hrtime     85  0.0 sleep 1000

这种行为的原因是什么?可以禁用吗?

What is the reason for this behavior? Can it be disabled?

推荐答案

当 shell 在后台运行一个程序时,后台进程不应该再绑定到原来的 shell——shell 可以退出或被被杀死,后台进程应该继续运行.

When a shell runs a program in the background, the background process is not supposed to be tied to the original shell any more -- the shell can exit or be killed, and the background process should continue running.

如果 shell 是交互式的并且正在使用作业控制,它会将后台进程放在一个单独的进程组中,因此发送到 shell 进程组的信号不会影响它.

If the shell is interactive and job control is being used, it puts the background process in a separate process group, so signals sent to the shell process group don't affect it.

但是当不使用作业控制时,这是非交互式 shell 中的默认设置,后台进程在同一个进程组中.为避免后台进程接收仅用于 shell 的键盘信号,它显然会忽略那些子进程中的这些信号.

But when job control is not being used, which is the default in non-interactive shells, the background process is in the same process group. To avoid the background process receiving keyboard signals that are just intended for the shell, it apparently ignores those signals in those child processes.

这篇关于为什么 shell 会忽略后台进程中的 SIGINT 和 SIGQUIT?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆