如何在脚本之间发送信号 SIGINT?

发布于 2024-08-27 09:50:30 字数 545 浏览 4 评论 0原文

我想捕获从 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 从一个脚本发送到另一个脚本吗?

I want to trap a signal send from Script-A.sh to Script-B.sh
so in Script-A.sh i use the command:

(Send SIGINT to Script-B.sh)
kill -2 $PID_Script-B.sh

And in Script-B.sh i catch the signal and call function Clean

trap 'Clean' 2

It does not work, instead the Script-B.sh is killed right away without performing the Clean !!

What i notice also is that if i want to send SIGINT from terminal to any script that traps it, a ctrl-c will be caught correctly, but not if i specify the signal via the command kill -2 $pid_of_script

Any idea about the difference between the two method to send the SIGINT (ctrl-c VS kill -2 $pid_of_script), and how i can send a SIGINT from a script to another?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

沫离伤花 2024-09-03 09:50:30

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

来自 info bash

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

我发现,如果您使用 SIGUSR1 等其他信号来陷阱杀死,它就会起作用。

来自<的其他信息代码>人bash:

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

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

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

I was able to reproduce the behavior you report. My hypothesis is that since the script is running from a non-interactive shell (as a child of a script) that SIGINT, which is a keyboard signal, is ignored.

From info bash:

Background processes are those whose process group ID differs from the
terminal's; such processes are immune to keyboard-generated signals.

I have found that if you trap and kill using another signal such as SIGUSR1 it works.

Additional information from man bash:

Non-builtin commands run by bash have signal handlers set to the values inherited by the shell from its parent. When job control is not in effect, asynchronous commands ignore SIGINT and SIGQUIT in addition to these inherited handlers.

and

If bash is waiting for a command to complete and receives a signal for which a trap has been set, the trap will not be executed until the command completes.

and

Any trap on SIGCHLD is executed for each child that exits.

痴者 2024-09-03 09:50:30

在脚本 A 中:陷阱函数如下所示,它将调用 scriptA.sh 中的 trap_mesg() 函数。 KILL 信号(2/中断,5/终止 - 默认)。您所要做的就是在从 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 ....”进行源代码/调用。

In script A: Trap function will look like following which will call trap_mesg() function in scriptA.sh. KILL Signal (2/INTerrupt, 5/TERMinate-default). All, you have to do is to get the PID of a runing scriptB.sh process/session once scriptB.sh is called from scriptA.sh (nohup ... & will give you or use ps command)

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
##################################

Now, within scriptB.sh, do the same/similar but just for scriptB trap job (like calling 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
##################################

This way, you dont have to source/call scriptB.sh within scriptA.sh as ". scriptB.sh ...."

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文