gpt4 book ai didi

linux - 用于启动进程的 Bash 脚本,随机等待,终止进程,重新启动

转载 作者:IT王子 更新时间:2023-10-29 00:17:24 25 4
gpt4 key购买 nike

我是一个绝对的初学者,我正在尝试创建一个 bash 脚本来随机化命令行应用程序的启动和退出。我计划在 autostart.sh 中稍作延迟后在启动时自动启动脚本 (Crunchbang)(在此处找到:http://interwebworld.co.uk/2011/10/23/how-to-launch-programs-automatically-at-startup-in-crunchbang-linux/)

(sleep 300s && /home/myuser/Scripts/randomizer.sh) &

这基本上是我需要在 randomizer.sh 脚本中用一些伪代码完成的:

start applicationfile
wait a random period of time
if applicationfile is still running
kill its process
wait a random period of time
exit this script and restart this script
else exit this script and restart this script

我目前拥有的 randomizer.sh 如下(包含伪代码的残余部分), sleep 延迟在此处找到:http://blog.buberel.org/2010/07/howto-random-sleep-duration-in-bash.html,欢迎提供帮助。

/path/to/applicationfile -s 111.222.333.444 -u username -p password
sleep $[ ( $RANDOM % 150 ) + 60 ]m
if applicationfile is still running
kill $(ps aux | grep '[u]sername' | awk '{print $2}')
sleep $[ ( $RANDOM % 150 ) + 60 ]m
exec $randomizer.sh
else exec $randomizer.sh

我“认为”非伪部分应该可以正常工作,但如果我错了请纠正我或进行调整。初始的 applicationfile 命令行按原样工作,我已经测试了进程终止行并且它按预期工作。 Applicationfile 没有从命令行结束自身的内置方法,但是远程机器上的死连接将在本地被杀死 5 分钟后被杀死,所以在本地杀死它可以满足我的需要。

我不知道如何处理 kill 上面的那一行,它首先检查进程“是否”正在运行。抱歉文字墙,但我想表明我已经尽我所能。

最佳答案

在 bash 中,$! 是最后启动的进程的 PID,所以按照这样的模式应该可以工作:

mycommand &
last_pid=$!
sleep( $RANDOM )
kill -KILL $last_pid

当然,您可以随意更改发送的信号、$RANDOM 与您想 sleep 的时间之间的关系等。

新进程不太可能获得相同的 PID,除非 a) 休眠时间很长或 b) 您的机器启动了很多短暂的进程。在 Linux 上,PID 是循环分配的,最大值为 32,765,因此,粗略地说,您必须在 sleep 时间内启动大约那么多的进程,才能冒着遇到属于不同进程的相同 PID 的风险。如果这是一个风险,您可以添加一个测试(从技术上讲,这里有一场比赛,但不太可能成为问题)。以下内容似乎可以满足您的要求。

signal=KILL

sleep_a_while () {
sleep $[ ( $RANDOM % 150 ) + 60 ]m
}

while true; do
# Note: command launched in background:
/path/to/applicationfile -s 111.222.333.444 -u username -p password &

# Save PID of command just launched:
last_pid=$!

# Sleep for a while:
sleep_a_while

# See if the command is still running, and kill it and sleep more if it is:
if ps -p $last_pid -o comm= | grep -qs '^applicationfile$'; then
kill -$signal $last_pid 2> /dev/null
sleep_a_while
fi

# Go back to the beginning and launch the command again
done

我用等效循环替换了 self-exec

kill 行,由于竞争,将 stderr 重定向到 /dev/null 是可取的。该进程可能会在 ps 完成和执行 kill 之间自然退出,从而产生无害的错误消息。这种竞争是不可避免的(也是无害的),除非 PID 存在的测试和信号的发送是重合的。

如果打算同时运行最多一个 applicationfile 实例,则可以通过替换来完全避免这种竞争:

# See if the command is still running, and kill it and sleep more if it is:
if ps -p $last_pid -o comm= | grep -qs '^applicationfile$'; then
kill -$signal $last_pid 2> /dev/null
sleep_a_while
fi

与:

killall -q applicationfile && sleep_a_while

如果这不能使用,Keith Reynolds 的测试变体更好,因为它避免了不必要的 grep,即使用:

# See if the command is still running, and kill it and sleep more if it is:
if [ "$(ps -p $last_pid -o comm=)" = "applicationfile" ]; then
kill -$signal $last_pid 2> /dev/null
sleep_a_while
fi

关于linux - 用于启动进程的 Bash 脚本,随机等待,终止进程,重新启动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22867130/

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