2016-07-26 71 views
3

今天我遇到了一個問題,由shell腳本啓動的程序無法接收INT信號。經過一番調查後,我會在下面展示我的發現。bash信號陷阱會覆蓋nohup子命令的信號嗎?

這是我要運行,我把它用gcc hello.c -o hello.out如果您手動啓動該程序編譯目標程序,您可以通過kill -2

#include <stdio.h> 
#include <unistd.h> 
#include <stdlib.h> 


int main() 
{ 
    while (1) { 
     printf("--------Hello Wolrd!\n"); 
     sleep(2); 
    } 
    return 0; 
} 

停止它,然後我有一個shell腳本,做一些處理在開始我的程序之前。這裏是簡潔版,姑且稱之爲trap.sh

#!/bin/bash 

pid=0 

function singal_handler() { 
    echo "pid is "$java_pid 
} 

trap "singal_handler" INT 

pid=2 

nohup ./hello.out & 

while true; do 
    echo "running...." 
    sleep 2 
done 

請注意,我用陷阱捕獲INT信號做我自己的工作,並且使用nohup開始我hello.out

現在我開始我的程序bash trap.sh

通過向我的trap.sh發佈kill -2,行爲是預期的,即PID輸出已經結束。

讓我感到驚訝的是,在這個時候,當我發出kill -2到我的背景hello.out時,hello.out仍然存在,它並沒有消失。

所以我寫這個問題,問爲什麼會發生這種情況。 bash trap將覆蓋其子命令的信號處理程序?

我的平臺是64位的Linux:

uname -r -----> 3.10.0-123.el7.x86_64

感謝。

回答

2

bash manual說:

當除了一個內置或殼功能的其它一個簡單的命令將被執行,則在其由以下的獨立的執行環境調用。除非另有說明,否則這些值是從shell繼承而來的。

  • 外殼的打開的文件,加上重定向指定命令
  • 當前工作目錄
  • 文件創建模式掩碼
  • shell變量和函數標記爲導出,沿任何修改和補充爲環境傳遞的命令導出的變量(請參閱環境)
  • 將由shell捕獲的陷阱重置爲從shell的父項繼承的值,並忽略被shell忽略的陷阱

man sigaction說:

通過fork創建子(2)繼承了其父的信號傾向的副本。在execve(2)期間,處理信號的配置默認重置爲 ;被忽略的信號的配置保持不變。

所以,SIGINT get被忽略,因爲父shell忽略它。

+0

謝謝。什麼是「默認」性格? 我對如何將陷阱從bash繼承到命令感到困惑https://unix.stackexchange.com/q/387038/674 – Tim