web-dev-qa-db-ja.com

SIGINTがバックグラウンドの子プロセスに伝播されていません

プロセスを正常に終了するには、SIGINTを送信する必要がありますが、送信できません。

実行が発生する環境は「不明」(travis.comのbashスクリプト)であるため、これはサンプルです。

このようなプロセスを起動することで、同じ動作を得る(シミュレートする)ことができました(command &) &

vagrant@Host:~$ (sleep 40 &) &
[1] 8473
vagrant@Host:~$ ps -o pid,pgid,args
  PID  PGID COMMAND                     
 2787  2787 -bash                       
 8474  8473 sleep 40                    
 8490  8490 ps -o pid,pgid,args  
[1]+  Done                    ( sleep 40 & )
vagrant@Host:~$ kill -INT 8474  ##### here I send SIGINT to the process
vagrant@Host:~$ kill -INT -8473 ##### here I send SIGINT to the process group
vagrant@Host:~$ ps -o pid,pgid,args
  PID  PGID COMMAND                     
 2787  2787 -bash                       
 8474  8473 sleep 40                    
 8559  8559 ps -o pid,pgid,args  

私はグーグルでシグナルやグループについてたくさん読んだのですが、ここで何が起こっているのか理解できません。信号はある時点で無視されていますか?何が起こっている? SIGINTをそのsleepプロセスに送信するにはどうすればよいですか?

[〜#〜] edit [〜#〜]SIGTERMが使用されている場合、プロセスは強制終了されます(おそらく、親サブシェルが強制終了されますか?)

6
jperelli

非対話型ジョブがSIGINTに応答するようにするには、SIGINTのハンドラーを作成する必要があります。

$ ( (trap "echo Got SigInt" SIGINT; sleep 60) & ) &
[1] 13619
$ 
[1]+  Done                    ( ( trap "echo Got SigInt" SIGINT; sleep 60 ) & )
$ ps -o pid,pgid,args
  PID  PGID COMMAND
11972 11972 bash
13620 13619 bash
13621 13619 sleep 60
13622 13622 ps -o pid,pgid,args
$ kill -INT 13620
$ kill -INT 13621
$ Got SigInt

SIGINTをスリーププロセスに送信する

StéphaneChazelasがコメントで示唆しているように、目標がSIGINTのデフォルトの動作に戻ることである場合は、trap - SIGINTを使用できます。例えば:

$ ( (trap - SIGINT; sleep 60) & ) &
[1] 16690
$ ps -o pid,pgid,args
  PID  PGID COMMAND
11972 11972 bash
16691 16690 bash
16692 16690 sleep 60
16693 16693 ps -o pid,pgid,args
[1]+  Done                    ( ( trap - SIGINT; sleep 60 ) & )
$ kill -INT 16692
$ ps -o pid,pgid,args
  PID  PGID COMMAND
11972 11972 bash
16698 16698 ps -o pid,pgid,args
4
John1024