bash脚本来启动进程,等待随机,杀进程,重启 [英] Bash script to start process, wait random, kill process, restart
问题描述
我是一个绝对的初学者,想创建一个bash脚本,以随机的命令行程序的启动和退出。我打算在autostart.sh(这里发现了以下有轻微的延迟后自动启动开机(Crunchbang)的脚本:<一href=\"http://interwebworld.co.uk/2011/10/23/how-to-launch-programs-automatically-at-startup-in-crunchbang-linux/\" rel=\"nofollow\">http://interwebworld.co.uk/2011/10/23/how-to-launch-programs-automatically-at-startup-in-crunchbang-linux/ )
I'm an absolute beginner and am trying to create a bash script to randomize the start and exit of a command line app. I plan to autostart the script on boot (Crunchbang) after a slight delay with the following in autostart.sh (found here: 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脚本来完成,在一个位伪code的:
This is essentially what I need to accomplish in the randomizer.sh script, in a bit of pseudocode:
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因为我有这到目前为止,哪些我要欢迎一些帮助,如下(含伪code的残余),发现睡眠延迟此处的 http://blog.buberel.org/2010/07/howto-随机睡眠时间,在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
我觉得非伪部分应该工作pretty多,因为他们有,但是请大家指正或调整,如果我错了。最初applicationfile命令行的工作,因为它是的,我已经测试过程中杀线,它按预期工作。 Applicationfile没有一个内置的方式,从命令行结束本身,而是在远程机器上的死连接会在5分钟被杀死局部后杀死,所以它杀死在本地满足我的需求是可以接受的。
I "think" the non-pseudo parts should work pretty much as they are, but please correct me or adjust if I'm wrong. The initial applicationfile command line works as it is, and I already tested the process kill line and it works as expected. Applicationfile doesn't have a built-in way to end itself from commandline, but the dead connection on the remote machine will be killed after 5 minutes of being killed locally, so killing it locally is acceptable for my needs.
我没有什么任何想法如何处理是杀,检查如果的过程是在第一个位置运行上面的行。对不起,文字的墙上,但我想证明我所做的,就像我已经能够。
What I don't have any idea how to handle is the line above the kill, which checks "if" the process is running in the first place. Sorry for the wall of text but I wanted to show I've done as much as I could already.
推荐答案
在bash中, $!
是最后一个推出进程的PID,这样的东西沿着线图案这应该工作:
In bash, $!
is the PID of the last launched process, so something patterned along the lines of this should work:
mycommand &
last_pid=$!
sleep( $RANDOM )
kill -KILL $last_pid
您当然可以,反复折腾来改变你发送的信号,$ RANDOM和你想睡觉的时间之间的关系,等等。
You can, of course, fiddle around to change the signal you send, the relationship between $RANDOM and the time you want to sleep, etc.
这有点不太可能,一个新的进程将得到同样的PID,除非或者a)睡眠时间很长或b)你的机器推出了很多短期的过程。在Linux上,PID被用32765一个最大循环分配的,因此,粗略地讲,你将不得不纷纷推出关于睡眠时间冒险击中属于不同的工艺相同的PID,许多进程。如果这是一个风险,你可以添加一个测试(从技术上讲,有一个在这里的比赛,但它不太可能是一个问题)。下面好像它会做你想做的。
It's somewhat unlikely that a new process will get the same PID unless either a) the sleep time is very long or b) your machine launches a lot of short-lived processes. On Linux, PIDs are allocated cyclically with a max of 32,765, so, roughly speaking, you would have to have launched about that many processes in the sleep time to risk hitting the same PID belonging to a different process. If that's a risk, you could add a test (technically, there's a race here, but it's very unlikely to be a problem). The following seems like it would do what you want.
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
我已经取代了自我 - EXEC
用等效循环
在杀
行标准错误
的重定向到的/ dev / null的
是因为一场比赛的期望。该进程可能的时间之间自然退出 PS
完成,时间的杀
被执行,导致无害错误信息。这场比赛是不可避免的(无害),除非该PID的存在和信号的发送测试是一致的。
On the kill
line, the redirect of stderr
to /dev/null
is desirable because of a race. The process might exit naturally between the time the ps
completes and the time that the kill
is executed, resulting in a harmless error message. This race is unavoidable (and harmless) unless the test that the PID exists and the sending of the signal are coincident.
如果有拟以最多的有一个的 applicationfile
在同一时间运行,则可以完全通过更换回避本场比赛的一个实例:
If there is intended to be at most one instance of applicationfile
running at a time, then this race can be avoided entirely by replacing:
# 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
如果这个不能用,测试的基思·雷诺兹的变种比较好,因为它避免了不必要的的grep
,即使用:
If this cannot be used, Keith Reynolds's variant of the test is better, since it avoids an unnecessary grep
, i.e. using:
# 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
这篇关于bash脚本来启动进程,等待随机,杀进程,重启的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!