为什么额外的一对陷阱和等待

why an extra pair of trap and wait

我有以下 bash 脚本,它 运行 是后台进程并等待它完成。如果它在中间终止,它应该在终止自身之前终止其 child 进程。

此脚本 运行 在 docker 容器中。

_term() {
  echo "SHELL: Caught SIGTERM signal, propagating to the child"
  kill -TERM "$child" 2>/dev/null
}

trap _term SIGTERM

java -jar RunningProcessWithJMX.jar & # in background

child=$!
wait "$child"  # Line #10
trap - SIGTERM # Line #11
wait "$child"  # Line #12
echo "SHELL: Task finished."

我能看懂这个脚本,除了陷阱并在第 11、#12 行等待。以下是我的疑惑-

  1. 根据 trap 的手册页,第 11 行正在重置 SIGTERM 上的操作。但是,如果 运行 将其放入 docker 容器中并且该过程的持续时间为 short/long,那么此步骤是否有任何优势?

If action is '−', the shell shall reset each condition to the default value.

  1. 据我了解,在第 10 行生成的进程 finished/terminated 之前,执行控制不会到达第 11 行。有人可以帮助我理解在第 12 行添加另一个等待有什么好处吗?目前,每当我 运行 这个脚本在 docker 容器之外时,它都会报告 child 已经终止。

这确实是个好问题。现在看下面:-

trap - SIGTERM # Line #11

当您将此信号发送到进程时,它不会立即自行终止。一旦进程收到此信号,它就可以执行某些操作,这在它杀死自己之前是至关重要的,并且可能需要一些时间才能完成。在 Java 中有一个方法调用 attachShutDownHook 我们是这样实现的。

private void attachShutDownHook() {
     Runtime.getRuntime().addShutdownHook(new Thread() {                 
         @Override   public void run() {
                System.out.println("Received signal to stop the application");
                System.out.println("Shuting down the application....");
                //here your codes what you want to do at this situation
             }   
         }
     ); 
}

所以现在当您执行trap 命令时,此方法将调用java 应用程序。 Java 虚拟机一旦接收到上述 trap 命令或类似 kill -8 的命令,将在当前 运行 的 java 应用程序中调用此方法。

wait "$child"  # Line #12

而且您一定要等到 child 完成其最后一个任务列表才能完成 insede attachShutDownHook 方法。

希望这会有所帮助。