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

查看:132
本文介绍了为什么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

这意味着,如果我从交互式父外壳程序(bash)运行kill -INT -$!(或fg,然后是Ctrl-C),则不会达到-c代码段背景下的睡眠过程并且可以继续存在. /p>

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中的默认设置),后台进程位于同一进程组中.为了避免后台进程接收仅用于外壳程序的键盘信号,它显然会忽略那些子进程中的那些信号.

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天全站免登陆