我已经四处寻找,但还没有找到我正在寻找的东西.简而言之,我创建了一个bash脚本,在无限循环中运行,睡眠并检查进程是否正在运行.唯一的问题是即使进程正在运行,也表示它不是并打开另一个实例.
我知道我应该按进程名称检查而不是进程ID,因为另一个进程可以跳入并获取id.但是,所有perl程序在我的系统上都命名为Perl5.10.0,我打算打开同一个perl程序的多个实例.
以下"if"总是返回false,我在这里做错了什么???
while true; do
if [ ps -p $pid ]; then
echo "Program running fine"
sleep 10
else
echo "Program being restarted\n"
perl program_name.pl &
sleep 5
read -r pid < "${filename}_pid.txt"
fi
done
Run Code Online (Sandbox Code Playgroud)
摆脱方括号.它应该是:
if ps -p $pid; then
Run Code Online (Sandbox Code Playgroud)
方括号是test命令的语法糖.这是一个完全不同的野兽,根本不会调用ps:
if test ps -p $pid; then
Run Code Online (Sandbox Code Playgroud)
事实上,当我运行它时会产生"-bash:[: - p:二元运算符预期".
除了已经指出的语法错误之外,这是确保进程保持活动的糟糕方式.
首先,你应该找出你的计划首先死亡的原因; 这个脚本没有修复bug,它试图隐藏一个.
其次,如果一个程序仍在运行非常重要,为什么你期望你的(至少已经有一次)有问题的shell脚本能够完成这项工作呢?使用专门用于重新启动服务器进程的系统工具.如果您说您正在使用的平台以及服务器进程的性质.我可以提供更具体的建议.
添加以回应评论:
当然,有工程需要,但正如OP中提到的OP,这个尝试的解决方案仍有一个错误:
我知道我应该按进程名称检查而不是进程ID,因为另一个进程可以跳入并获取id.
所以现在你留下了一个PID跟踪脚本,而不是一个过程"保姆".虽然机会很小,但现在的脚本有一个十秒钟的窗口
该脚本不仅仅是错误的,它是无效的,因为它假定PID是进程的稳定标识符.有一些方法可以更好地处理,即使在shell脚本级别.最简单的是永远不要perl从脚本中分离执行,因为除了观察子进程之外,脚本什么都不做.例如:
while true ; do
if perl program_name.pl ; then
echo "program_name terminated normally, restarting"
else
echo "oops program_name died again, restarting"
fi
done
Run Code Online (Sandbox Code Playgroud)
这不仅更短更简单,而且它实际上阻止了您真正感兴趣的条件:perl程序的运行状态.原始脚本重复检查运行状态条件(PID)的错误代理指示,因此可能会出错.并且,由于这个保姆脚本的整个目的是处理故障,如果设计本身有缺陷则会很糟糕.