【问题标题】:bash trap of TERM - what am I doing wrong?术语的 bash 陷阱 - 我做错了什么?
【发布时间】:2009-10-06 16:42:04
【问题描述】:

鉴于这个 hack.c 程序:

#include <stdio.h>
main()
{
 int i=0;
 for(i=0; i<100; i++) {
   printf("%d\n", i);
   sleep(5);
 }
}

还有这个 hack.sh bash 脚本:

#!/bin/bash
./hack

如果我运行 hack.sh,会创建两个进程 - 一个用于 bash,一个用于 C 任务。如果 TERM 信号被发送到 bash 进程,C 进程不会受到伤害。

现在,假设原始 bash 是使用 Runtime.exec() 从 Java 程序启动的,那么我对它的唯一控制是 Process.destroy()(它将 TERM 发送到 bash 进程)?假设我希望 C 进程与启动它的 bash 一起死掉?

我一直在 bash 中尝试这样的事情:

#!/bin/bash
trap "kill -TERM -$$; exit" TERM
./hack

即捕获 TERM 信号并将其重新广播到整个进程组的陷阱子句。这对我不起作用 - 一个带有陷阱子句的 bash 进程忽略 TERM 信号。

我在这里错过了什么?

【问题讨论】:

  • bash 的手册页说:如果 bash 正在等待命令完成并接收到已设置陷阱的信号,则在命令完成之前不会执行陷阱。
  • 您是否尝试过使用exec 而不是保持shell 进程处于活动状态?
  • 你说得对,唐根斯。我唯一的借口是文本在信号部分,在陷阱文档的上方。谢谢!

标签: bash signals bash-trap


【解决方案1】:

您可以尝试以下方法:

#!/bin/bash
./hack &
pid=$!
trap "kill $pid" TERM
wait $pid

这样做可能更简单(和等效):

#!/bin/bash
./hack &
trap "kill $!" TERM
wait

陷阱上的双引号应该在定义陷阱时发生单词扩展,因此 $!不应该有影响;但我更喜欢第一个版本。

【讨论】:

  • 这行得通,尽管您可能认为它不是因为 tangens 在问题的 cmets 中所说的。但完整的段落,部分由 tangens 引用,说:
  • 如果 bash 正在等待命令完成并接收到已设置陷阱的信号,则在命令完成之前不会执行陷阱。当 bash 通过 wait builtin 等待异步命令时,接收到设置了陷阱的信号将导致 wait builtin 立即返回,退出状态大于 128,然后立即执行陷阱。
  • 还想补充一点,您可以通过以下方式杀死整个进程组(进程本身及其子进程):kill -TERM -$$
猜你喜欢
  • 1970-01-01
  • 2011-12-13
  • 2016-12-18
  • 1970-01-01
  • 2011-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-08
相关资源
最近更新 更多