gpt4 book ai didi

bash - 如何在 bash 中重启进程或按命令终止进程?

转载 作者:行者123 更新时间:2023-11-29 09:14:02 27 4
gpt4 key购买 nike

我有一个脚本可以跟踪一个进程,如果该进程终止,它将重新生成。我希望跟踪脚本也可以通过给跟踪脚本一个 sigterm(例如)来终止进程。换句话说,如果我终止跟踪脚本,它也应该终止它正在跟踪的进程,不再重生并退出。

拼凑几篇文章(我认为这是最佳实践,例如不要使用 PID 文件),我得到以下信息:

#!/bin/bash

DESC="Foo Manager"
EXEC="python /myPath/bin/FooManager.pyc"

trap "BREAK=1;pkill -HUP -P $BASHPID;exit 0" SIGHUP SIGINT SIGTERM

until $EXEC
do
echo "Server $DESC crashed with exit code $?. Restarting..." >&2
((BREAK!=0)) && echo "Breaking" && exit 1
sleep 1
done

所以,现在如果我在一个 xterm 中运行这个脚本。然后在另一个 xterm 中我发送类似这样的脚本:

kill -HUP <tracking_script_pid>  # Doesn't work.
kill -TERM <tracking_script_pid> #Doesn't work.

跟踪脚本没有结束或任何东西。如果我从命令行运行 FooManager.pyc,它将在收到 SIGHUP 和 SIGTERM 时死掉。无论如何,我在这里做错了什么,也许有一种完全不同的方法可以做到这一点?

谢谢。

最佳答案

来自手册:

If Bash is waiting for a command to complete and receives a signal for which a trap has been set, the trap will not be executed until the command completes. When Bash is waiting for an asynchronous command via the wait builtin, the reception of a signal for which a trap has been set will cause the wait builtin to return immediately with an exit status greater than 128, immediately after which the trap is executed.

重点是我的。

所以在你的情况下,当你的命令正在执行时,Bash 会等到它结束才会触发陷阱。

要解决此问题,您需要将程序作为作业运行,然后等待。如果您的程序永远不会以大于 128 的返回码退出,您可以简化以下代码,但我不做这个假设:

#!/bin/bash

desc="Foo Manager"
to_exec=( python "/myPath/bin/FooManager.pyc" )

trap 'trap_triggered=true' SIGHUP SIGINT SIGTERM

trap_triggered=false
while ! $trap_triggered; do
"${to_exec[@]}" &
job_pid=$!
wait $job_pid
job_ret=$?
if [[ $job_ret = 0 ]]; then
echo >&2 "Job ended gracefully with no errors... quitting..."
break
elif ! $trap_triggered; then
echo >&2 "Server $desc crashed with exit code $job_ret. Restarting..."
else
printf >&2 "Received fatal signal... "
if kill -0 $job_pid >&/dev/null; then
printf >&2 "killing job $job_pid... "
kill $job_pid
wait $job_pid
fi
printf >&2 "quitting...\n"
fi
done

注释。

  1. 我使用小写变量名,因为大写被认为是不好的做法:它们可能与 Bash 的保留名称或环境变量冲突。
  2. 我没有使用字符串 来存储命令,而是使用数组。对于字符串,如果您想将空格等有趣的字符作为参数传递,就会遇到很多问题。使用正确引用的数组,您不会有任何问题。 (有些人会争辩说使用函数会更好。)

关于bash - 如何在 bash 中重启进程或按命令终止进程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27607772/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com