C bash中程序的陷阱杀死

C bash中程序的陷阱杀死,c,bash,C,Bash,我正在尝试的是,我的c示例有kill(),它杀死一个进程。但我想通过bash脚本捕捉杀戮,以便正确执行 我有一个杀死进程的小例子 #include <signal.h> int main(void) { printf("before kill"); kill(0, SIGTERM); // 2265 is a process pid id printf("after kill"); } #include <signal.h> int main(void)

我正在尝试的是,我的c示例有kill(),它杀死一个进程。但我想通过bash脚本捕捉杀戮,以便正确执行

我有一个杀死进程的小例子

#include <signal.h>

int main(void)
{
  printf("before kill");
  kill(0, SIGTERM); // 2265 is a process pid id
  printf("after kill");
}
#include <signal.h>

int main(void)
{

  kill(0, SIGTERM);
}
但它什么也没做。非常感谢您的任何建议或帮助。

Shell信号处理 我有一个杀死进程的小例子

#include <signal.h>

int main(void)
{
  printf("before kill");
  kill(0, SIGTERM); // 2265 is a process pid id
  printf("after kill");
}
#include <signal.h>

int main(void)
{

  kill(0, SIGTERM);
}
但它什么也没做

假设
/helloapp
是发送信号的过程,那么您完全误解了bash的信号处理风格。我怀疑这可能反映了对一般信号处理的误解

您编写了信号处理函数,就好像它为Java中的
try
块中的命令提供了某种信号处理范围一样。但信号与Java异常并不相似。它们是异步的,超出了正常的控制流。异常可以产生本来不可能实现的控制权转移,但它们仍然在整个程序流中运行。但信号处理并非如此

Bash
trap
命令不执行命名的shell函数。而是将其注册为指定信号的处理程序。如果该shell进程随后接收到一个指定的信号,那么函数将运行,而不是该信号的默认行为。在这种情况下,如果进程向其发送
SIGTERM
,则可以防止shell本身终止。适当的语法如下所示:

#!/usr/bin/env bash

# define signal handler
term_handler() {
  echo "bash caught TERM but refuses to terminate"
}

# register signal handler
trap term SIGTERM

# run process that might send a signal
./helloapp
还要注意,shell将捕获来自任何源的信号,而不仅仅是来自它自己运行的命令

但是您在评论中澄清,您真正想要的是在调用
kill()
之后继续执行
/helloapp
。这不是通过启动进程的shell中的陷阱可以实现的。陷阱处理传递给外壳本身的信号,而不是传递给任何其他进程的信号


你能做些什么 因此,要明确的是,您的进程似乎没有通过
kill()
的原因是它本身就是
SIGTERM
交付到的进程之一,而
SIGTERM
的默认处理是进程终止。当它接收到自己的信号时,它终止。您有两种选择来避免这种情况:

  • 让流程避免自己发出信号。可能的途径有

    • 让其发出特定流程的信号,而不是其流程组中的所有流程

      kill(a_positive_pid_different_from_mine, SIGTERM);
      
    • 让它记录其原始进程组编号,然后在终止原始进程组之前将自己放入新的进程组中。假设流程尚未成为流程组长,则可能是:

      pid_t original_pg = getpgid(0);
      setpgid(0, 0);
      kill(-original_pg, SIGTERM);
      
  • 让进程本身为信号注册一个处理程序。例如,这将使进程忽略它接收到的下一个
    SIGTERM

    struct sigaction action = { .sa_handler = SIG_IGN, .sa_flags = SA_RESETHAND };
    sigaction(SIGTERM, &action, NULL);
    

  • 当然,您必须始终检查函数返回值并正确处理它们,至少在您关心它们是否成功完成和/或它们做了什么的时候。为清晰起见,上述代码片段中省略了此类检查。

    首先,如果捕获了
    SIGTERM
    ,则运行您的程序,而不是运行它来抛出
    SIGTERM
    。我不确定是否遵循。您是在试图阻止进程终止shell还是终止其他进程?您的shell脚本将无法截获用于其他进程的信号。如果其他人向您的C程序发送终止信号,您的shell脚本将无法对此执行任何操作。(如果C程序像这里看起来的那样自杀,情况就更糟了。)但是,shell脚本可以监视C程序并在退出后执行某些操作。这就是你要找的吗?@bruno,
    kill(0,SIGTERM)
    并不意味着“向pid为0的进程发送一个
    SIGTERM
    ”,而是意味着“向这个进程组中的每个进程发送一个
    SIGTERM
    ”。没有充分的理由同时拥有一个自定义编写的程序和一个自定义shell脚本。要么程序用于发送信号,您可以仅使用标准的
    kill
    命令(该命令将同样有效地发送信号)复制行为,从而从您的问题中完全删除
    c
    ,要么程序不用于发送信号,您可以从您的问题中完全删除
    bash
    。不管是哪种方式,这个问题都应该进一步缩小,然后才能在这里提出。