[英]Bash script to start process, wait random, kill process, restart
我是一个绝对的初学者,我正在尝试创建一个bash脚本来随机化命令行应用程序的启动和退出。 我计划在autostart.sh中稍后延迟使用以下内容自动启动脚本(Crunchbang)(在此处找到: http : //interwebworld.co.uk/2011/10/23/how-to-launch-programs-自动启动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,我欢迎一些帮助,如下(包含伪代码的残余),以及在这里找到的睡眠延迟: 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
我“认为”非伪部分应该像它们一样工作,但如果我错了,请纠正我或调整。 初始applicationfile命令行按原样工作,我已经测试了进程kill行,它按预期工作。 Applicationfile没有内置的方法从命令行结束自己,但远程机器上的死连接将在本地被杀死5分钟后被终止,因此在本地杀死它是可以接受的。
我不知道如何处理的是kill之上的行,它首先检查进程是否正在运行。 对不起文字的墙,但我想表明我已经做了尽可能多的事情。
在bash, $!
是最后一个启动过程的PID,所以沿着这个方向构图的东西应该有效:
mycommand &
last_pid=$!
sleep( $RANDOM )
kill -KILL $last_pid
当然,你可以改变你发送的信号,$ RANDOM和你想睡觉的时间等之间的关系。
除非a)睡眠时间很长或b)你的机器启动了许多短期过程,否则新进程获得相同PID的可能性不大。 在Linux上,PID周期性地分配,最大值为32,765,因此,粗略地说,您必须在睡眠时间内启动许多进程才有可能触及属于不同进程的相同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
我已经用等效循环替换了自我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
尝试使用randomizer.sh的此代码
min_val=60
range=150
while true ; do
run_this_command &
last_pid=$!
sleep $[ ( $RANDOM % $range ) + $min_val ]
{ [ "$(ps -p $last_pid -o comm= )" ] && \
[ "$(ps -p $last_pid -o comm= )" = run_this_command ];
} && { kill -KILL $last_pid ;}
done
一些说明:
{ [ condition ] && { command ;} && command
比if [ condition ]; then command, else command; fi
运行得更快if [ condition ]; then command, else command; fi
if [ condition ]; then command, else command; fi
ps -p $last_pid -o comm=
将使用$last_pid
的PID吐出进程的名称。 如果没有具有该值的PID,则其存在的代码为1。 修改以满足开始要求之前的额外随机等待期:
# Minimum and range values for random Wait before start in seconds
MinA=60;RangeA=150
# Minimum and range values for random Wait before kill in seconds
MinB=60; RangeB=150 #
while true ; do
sleep $[ ( $RANDOM % $RangeA ) + $MinA ]
run_this_command &
last_pid=$!
sleep $[ ( $RANDOM % $RangeB ) + $MinB ]
{ [ "$(ps -p $last_pid -o comm= )" ] && \
[ "$(ps -p $last_pid -o comm= )" = run_this_command ]
} && \{ kill -KILL $last_pid ;}
done
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.