我正在为应用程序编写一个bash包装器。该包装器负责更改用户,运行软件和记录其输出。 我也希望它传播SIGINT信号。
到目前为止,这是我的代码:
#!/bin/bash
set -e; set -u
function child_of {
ps --ppid $1 -o "pid" --no-headers | head -n1
}
function handle_int {
echo "Received SIGINT"
kill -int $(child_of $SU_PID)
}
su myuser -p -c "bash /opt/loop.sh 2>&1 | tee -i >(logger -t mytag)" &
SU_PID=$!
trap "handle_int" SIGINT
wait $SU_PID
echo "This is the end."
我的问题是,当我向这个包装器发送一个SIGINT时,handle_int
被调用但脚本结束了,而我希望它继续等待$SU_PID
。
有没有办法捕获int信号,做一些事情然后阻止脚本终止?
答案 0 :(得分:4)
你有一个问题:在Ctrl-C之后,“这就是结束。”预计但它永远不会到来,因为脚本已经过早退出。原因是wait
在set -e
下运行时(意外地)返回非零值。
根据“男子狂欢”:
如果bash正在等待命令完成并收到已设置陷阱的信号,则陷阱 在命令完成之前不会执行。当bash正在等待异步命令时 等待内置,接收到已设置陷阱的信号将导致等待内置返回 立即使用退出状态大于128 ,然后立即执行陷阱。
您应该将wait
调用包装在set +e
中,以便在等待异步命令时处理陷阱信号后程序可以继续运行。
像这样:
# wait function that handles trapped signal on asynchronous commands.
function safe_async_wait {
set +e
wait $1 # returns >128 on asynchronous commands
set -e
}
#...
safe_async_wait $SU_PID