我有一个 cron 条目被卡住了,无法摆脱。 cron 作业启动一个脚本,该脚本为我们的应用程序系统运行夜间作业。该脚本在我们的应用程序系统的作业调度程序中提交异步作业。我们有几个步骤需要等待完成才能继续下一项工作。为了控制这一点,我们测试来自应用程序服务器的返回代码。如果作业的状态大于 59,则它仍在运行。因此,以下代码(没有“getjobstatus”命令,但假设它向下面的 jobstatus 返回一个数值):
jobstatus=0
while [[ $jobstatus -lt 60 ]]
do
sleep 5
jobstatus=`getstatus whatever`
done
我试图杀死“睡眠”过程,但它不断回来。我该如何预防并永久消灭它?
答案1
正如Deathgrip在评论中提到的,你必须杀死父进程,sleep
你可以找到它的一些变体ps | grep sleep
(ps
有很多实现,所以我不会准确猜测你需要提供什么标志或你的输出是什么样的。检查man ps
)
这是怎么回事?当您杀死sleep
它时,它会终止,但这不会影响包含脚本的执行...它只是移动到下一行并且循环不断循环。您可以通过多种方法修改脚本,以便终止睡眠。最简单的方法之一是执行以下操作:sleep 5 || exit
.
或者,如果您使用的是 Bash(其他?),您可以在开头添加此行:set -e
。这告诉 Bash 在任何命令失败时终止脚本(即返回非零状态)。但这会影响脚本中的所有内容,并有许多其他陷阱,因此最好避免该解决方案。 (您可以set -e
在睡眠前添加线路并set +e
在其后立即禁用,但这有点荒谬,因为您可以使用我提到的第一个解决方案。)
答案2
如果您有一个sleep
进程,并且该 sleep 进程是循环运行的父 shell 脚本的一部分(就像您所拥有的那样),那么您将必须终止该父进程以防止该(特定) sleep 命令被执行。又开始了。
获取该睡眠进程的 PID 并找到父进程,然后杀死它:
$ ps -e -opid,comm,args|grep sleep
424241 sleep sleep 999 # for example
$ ps -oppid= -p SLEEP-PID-HERE-SUCH-AS-424241-ABOVE
424242 # for example
$ kill $(ps -oppid= -p SLEEP-PID-HERE-SUCH-AS-424241-ABOVE)
答案3
我想你可能想要这样的东西: 如何在终端中停止循环 bash 脚本?
因此,在您的情况下,如果您使用 SIGTERM 而不是 INT,因为作为 cron 作业,我假设您尝试使用“kill”而不是 ctrl+C 来杀死它:
jobstatus=0
trap "exit" SIGTERM
while [[ $jobstatus -lt 60 ]]
do
sleep 5
jobstatus=`getstatus whatever`
done
应该允许杀死整个脚本而不仅仅是睡眠命令
很抱歉将其作为单独的答案而不仅仅是评论,但我还没有足够的积分来发表评论。