我需要为bash进程设置一个陷阱,我将在后台启动。后台进程可能会运行很长时间并将其PID保存在特定文件中。
现在我需要为该进程设置一个陷阱,所以如果它终止,PID文件将被删除。
我有办法做到吗?
我对问题的描述看起来不够精确。我可以完全控制所有代码,但我拥有的长时间运行后台进程是:
cat /dev/random >> myfile&
当我现在在脚本开头添加陷阱时,这个语句就在,$$
将是那个更大的脚本的PID而不是我从这里开始的这个小后台进程。
那么如何具体设置该后台进程的陷阱呢?
答案 0 :(得分:2)
(./jobsworthy& echo $! > $pidfile; wait; rm -f $pidfile)&
disown
答案 1 :(得分:0)
将其添加到Bash脚本的开头。
#!/bin/bash
trap 'rm "$pidfile"; exit' EXIT SIGQUIT SIGINT SIGSTOP SIGTERM ERR
pidfile=$(tempfile -p foo -s $$)
echo $$ > "$pidfile"
# from here, do your long running process
答案 2 :(得分:0)
在后台进程终止后,你不需要trap
只运行一些命令,你可以通过shell命令行运行并在后台进程之后添加命令,用分号分隔(并让这个shell在后台运行而不是后台进程)。
如果您仍希望在shell脚本中发送一些通知,请发送trap SIGUSR2
,例如:
#!/bin/sh
BACKGROUND_PROCESS=xterm # for my testing, replace with what you have
sh -c "$BACKGROUND_PROCESS; rm -f the_pid_file; kill -USR2 $$" &
trap "echo $BACKGROUND_PROCESS ended" USR2
while sleep 1
do
echo -n .
done
答案 3 :(得分:0)
您可以在显式子shell中运行长时间运行的后台进程,如Petesh的回答所示,并在此特定子shell中设置陷阱以处理退出长时间运行的后台进程。父shell不受此子shell陷阱的影响。
(
trap '
trap - EXIT ERR
kill -0 ${!} 1>/dev/null 2>&1 && kill ${!}
rm -f pidfile.pid
exit
' EXIT QUIT INT STOP TERM ERR
# simulate background process
sleep 15 &
echo ${!} > pidfile.pid
wait
) &
disown
# remove background process by hand
# kill -TERM ${!}