8

我需要为我在后台启动的 bash 进程设置一个陷阱。后台进程可能会运行很长时间,并将其 PID 保存在特定文件中。

现在我需要为该进程设置一个陷阱,所以如果它终止,PID 文件将被删除。

有没有办法我可以做到这一点?

编辑#1

看来我对问题的描述不够准确。我可以完全控制所有代码,但是我拥有的长时间运行的后台进程是这样​​的:

cat /dev/random >> myfile&

当我现在在该语句所在的脚本开头添加陷阱时,$$将是那个更大脚本的 PID,而不是我从这里开始的这个小后台进程的 PID。

那么如何专门为该后台进程设置陷阱呢?

4

4 回答 4

3
(./jobsworthy& echo $! > $pidfile; wait; rm -f $pidfile)&
disown
于 2011-03-07T00:34:19.790 回答
0

您可以在显式子shell中运行长时间运行的后台进程,如Petesh的回答所示,并在此特定子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 ${!}
于 2013-03-17T17:16:03.563 回答
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
于 2011-03-07T00:48:25.363 回答
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
于 2011-03-20T00:12:38.530 回答