【问题标题】:How to send a signal SIGINT from script to script?如何从脚本向脚本发送信号 SIGINT?
【发布时间】:2010-03-26 16:32:57
【问题描述】:

我想捕获从 Script-A.sh 发送到 Script-B.sh 的信号 所以在 Script-A.sh 我使用命令:

(发送 SIGINT 到 Script-B.sh)
杀死 -2 $PID_Script-B.sh

在 Script-B.sh 中我捕捉到信号并调用函数 Clean

陷阱'清洁'2

它不起作用,而是立即杀死 Script-B.sh 而不执行 Clean !!

我还注意到,如果我想将 SIGINT 从终端发送到任何捕获它的脚本,ctrl-c 将被正确捕获,但如果我通过命令 kill -2 $pid_of_script 指定信号则不会被捕获

关于发送 SIGINT (ctrl-c VS kill -2 $pid_of_script) 的两种方法之间的区别,以及如何将 SIGINT 从脚本发送到另一个?

【问题讨论】:

    标签: bash signals kill bash-trap


    【解决方案1】:

    我能够重现您报告的行为。我的假设是,由于脚本运行 一个非交互式外壳(作为脚本的子级),因此 SIGINT 是一个键盘信号,将被忽略.

    来自info bash

    后台进程是那些进程组 ID 不同于 终端;此类进程不受键盘生成的信号的影响。

    我发现如果你 trapkill 使用另一个信号,例如 SIGUSR1,它可以工作。

    来自man bash的更多信息:

    由 bash 运行的非内置命令将信号处理程序设置为 shell 从其父级继承的值。当作业控制无效时,除了这些继承的处理程序之外,异步命令还会忽略 SIGINT 和 SIGQUIT。

    如果 bash 正在等待命令完成并接收到已设置陷阱的信号,则在命令完成之前不会执行陷阱。

    SIGCHLD 上的任何陷阱都会针对每个退出的子节点执行。

    【讨论】:

    • bash(1) 的第一个位似乎是一个解释。此外,zsh 似乎工作正常。
    • 抱歉这个迟到的答案。你是对的,不是所有的信号都能被孩子捕捉到,但有一些。 SIGUSR1 和 SIGTERM 一样为我工作,但并非在所有 bash 版本中,因为我在尝试将信号从父亲发送给儿子时从 bash 3.00.16 中的脚本中遇到分段错误!其他时候使用相同的版本,它只会忽略信号而不捕捉它(在儿童级别)。但是较新的版本运行良好并且可以正确传播所有信号。非常感谢您的帮助
    • 好的。运行 scriptA shell 脚本并像“.scriptB.sh param1 param2 .. paramN”一样调用 scriptB(获取它),这样,它将为 Sig 2/INT 捕获干净
    • @ArunSangal: ...因为scriptB 不是孩子,所以它被视为scriptA 的一部分。
    • SIGUSR1 对我不起作用。我所做的是在前台启动一个 scriptA,然后从另一个 shell 发送 kill -SIGUSR1 pidof(scriptA)。什么都没发生。我究竟做错了什么 ? function iAmDone { echo "Trapped Signal" exit 0 } trap iAmDone SIGUSR1 echo "Running... " tail -f /dev/null # Do nothing 我从另一个 shell 执行 kill -SIGUSR1 ps aux | grep [t]est_trap | awk '{print $2}'
    【解决方案2】:

    在脚本 A 中:Trap 函数如下所示,它将调用 scriptA.sh 中的 trap_mesg() 函数。 KILL 信号(2/INTerrupt,5/TERMinate-默认)。你所要做的就是在从 scriptA.sh 调用 scriptB.sh 后获取正在运行的 scriptB.sh 进程/会话的 PID(nohup ... & 会给你或使用 ps 命令)

    trap_mesg ()
    {
     #...do something here for script B..
     # i.e. 
     kill -2 PID_of_ScriptB.sh_running_process_session
     sleep 10; #just in case, not reqd though.
     #show using ps -eAf|grep "scriptB" ... if null means, scriptB is gone. user is happy now.
     #...before actually exiting out...
     #show script A is exiting out as ScriptB is dead already, time for scriptA now.
     #...do something here..
    }
    
    #####################################
    ## Trap signals : INT, TERM. catch ##
    #####################################
    #Set NULL/Blank value to trap_call. This variable will help in running trap_mesg only once during the life of this script.
    trap_call="";
    
    trap 'if [ -z ${trap_call} ]; then trap_call="1"; trap_mesg ; fi' 2 15
    ##################################
    




    现在,在 scriptB.sh 中,执行相同/类似的操作,但仅针对 scriptB 陷阱作业(例如调用 clean)。

    clean ()
    {
    echo "karoge seva to milega meva"; 
    rm -fr /some/folder_file
    }
    
    trap_mesg ()
    {
     #...do something here JUST for script B trap message work..
     # i.e. 
     clean;
     #...do something here..
    }
    
    #####################################
    ## Trap signals : INT, TERM. catch ##
    #####################################
    #Set NULL/Blank value to trap_call. This variable will help in running trap_mesg only once during the life of this script.
    trap_call="";
    
    trap 'if [ -z ${trap_call} ]; then trap_call="1"; trap_mesg ; fi' 2 15
    ##################################
    

    这样,您不必将 scriptA.sh 中的 scriptB.sh 源/调用为“.scriptB.sh ....”

    【讨论】:

      猜你喜欢
      • 2010-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-13
      • 1970-01-01
      • 1970-01-01
      • 2021-01-06
      相关资源
      最近更新 更多