陷阱不在shell脚本中工作?

jph*_*jph 7 unix bash shell process

我正在OS X上编写脚本,需要捕获SIGTERM以便在退出之前杀死一些子进程.为了这个问题,我把它归结为以下最小的例子,由于某种原因,它不能正常工作,因为我期望它:

#!/bin/sh

function shutdown()
{
  touch foo.txt
  exit 0
}

trap shutdown TERM
su -l myusername -c "sleep 9999"
Run Code Online (Sandbox Code Playgroud)

我在一个终端窗口中运行此脚本,然后切换到另一个,"ps -aef"产生这个:

  502   857   645   0 11:38PM ttys001    0:00.00 /bin/sh ./foo.sh
    0   858   857   0 11:38PM ttys001    0:00.02 su -l myusername -c sleep 9999
  502   859   858   0 11:38PM ttys001    0:00.00 sleep 9999
Run Code Online (Sandbox Code Playgroud)

从那个第二个窗口开始,我发出"kill -15 857",但永远不会触发陷阱.脚本在"su"命令上仍然被阻止.

知道为什么吗?我觉得这很简单.

Edo*_*iel 13

bash的手册指出的是:

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

正如gniourf_gniourf所说,这是一个相对于shell中信号的POSIX规范.

您可以通过捕获例如SIGUSR1代替SIGTERM来检查它; 你会看到它kill -TERM会再次杀死这个过程.

解决方案是在后台运行命令,然后wait终止它.在这种情况下,trap将工作.试试这个:

#! /bin/bash

shutdown()
{
    touch foo.txt
    exit 0
}

trap shutdown TERM
su -l myusername -c "sleep 9999" &    # On Ubuntu: sudo su
wait
Run Code Online (Sandbox Code Playgroud)

你会遇到两个问题:su无法在前台询问密码; 你将不得不手动杀死su.