在 bash 中为 PID 已知的不同进程设置陷阱

发布于 2024-10-20 11:46:02 字数 368 浏览 1 评论 0原文

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

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

我有办法做到这一点吗?

编辑#1

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

cat /dev/random >> myfile&

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

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

I need to set a trap for a bash process I'm starting in the background. The background process may run very long and has its PID saved in a specific file.

Now I need to set a trap for that process, so if it terminates, the PID file will be deleted.

Is there a way I can do that?

EDIT #1

It looks like I was not precise enough with my description of the problem. I have full control over all the code, but the long running background process I have is this:

cat /dev/random >> myfile&

When I now add the trap at the beginning of the script this statement is in, $$ will be the PID of that bigger script not of this small background process I am starting here.

So how can I set traps for that background process specifically?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

清眉祭 2024-10-27 11:46:02
(./jobsworthy& echo $! > $pidfile; wait; rm -f $pidfile)&
disown
(./jobsworthy& echo $! > $pidfile; wait; rm -f $pidfile)&
disown
携余温的黄昏 2024-10-27 11:46:02

将其添加到 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

Add this to the beginning of your Bash script.

#!/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
旧情别恋 2024-10-27 11:46:02

您可以在显式子 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 ${!}

You can run your long running background process in an explicit subshell, as already shown by Petesh's answer, and set a trap inside this specific subshell to handle the exiting of your long running background process. The parent shell remains unaffected by this subshell trap.

(
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 ${!}
难以启齿的温柔 2024-10-27 11:46:02

您不需要 trap 在后台进程终止后运行某些命令,您可以通过 shell 命令行运行并在后台进程后面添加以下命令,用分号分隔(并让此 shell在后台运行而不是后台进程)。

如果您仍然希望在 shell 脚本中发送一些通知并捕获 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

You do not need trap to just run some command after a background process terminates, you can instead run through a shell command line and add the command following after the background process, separated with semicolon (and let this shell run in the background instead of the background process).

If you still would like to have some notification in your shell script send and trap SIGUSR2 for instance:

#!/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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文