Bash脚本和cron异常

时间:2009-12-14 16:03:29

标签: linux bash cron

我有一个bash脚本,我运行以检查我的某个程序是否已挂起,以及是否已将其删除。如果从命令行运行该脚本可以正常工作,但如果我使用cron安排它,它会做一些非常奇怪的事情。

基本上,脚本(下面)获取程序的PID,并从/ proc /目录中的条目获取其创建的日期/时间。然后它从系统获取当前日期/时间,并在自1970年以来使用“date”命令将这两个值转换为秒,然后再减去两者。这通常最终会持续2100秒或类似的事情,相当于35分钟。

#!/bin/bash
THEDATE=$(date +%s)
MYPID=$(ps aux|grep -v grep|egrep "MyProgram.exe"|awk '{print $2}')
if (( ${#MYPID} > 0 )); then
    STARTTIME=$(ls -ld /proc/$MYPID|date +%s -d"$(awk '{print $6, $7}')")
    TOTALMINS=$(( ($THEDATE - $STARTTIME) / 60  ))
    if (( $TOTALMINS >= 30 )); then
        kill -9 $MYPID
        logger -t "[KillLongRunningProcesses] Killed my program which had been running for $TOTALMINS minutes"
    fi
fi

从命令行运行时,两个日期变量(THEDATE和STARTTIME)都获得正确的值。但是当由cron运行时,STARTTIME是错误的。它有正确的日期,但似乎忽略时间部分并将其设置为午夜,即获得“2009-12-14 00:00:00”而不是“2009-12-14 13:23:00”,其中抛弃了所有的计算。

有什么想法吗?感谢。

4 个答案:

答案 0 :(得分:2)

这就是为什么你不能依赖parsing ls。如果您的系统有,请使用stat

stat --printf=%Y /proc/$MYPID

如果没有,也许您的find可以为您完成:

find /proc -maxdepth 1 -name $MYPID -printf "%T@"

答案 1 :(得分:2)

首先关闭 从不 解析ls的输出,阅读THIS以了解原因。接下来,使用pgrep而不是使用awk从'ps aux'上的grep解析PID,可以大大改善您的脚本。此外,在您返回多个PID的情况下,您的脚本会崩溃。最后,在编写shell脚本时尽量不要使用CAPITALS作为变量名;该约定保留给您export进入您的环境的变量。

以下脚本试图解决上述问题。它尽可能高效,它可以处理多个PID的情况。它还检查以确保在我们杀死之前PID仍然存在,因为当我们杀死父级时它可能会取出子进程。

#!/bin/bash

prog_name="MyProgram.exe"
the_date=$(date +%s)
my_pids=( $(pgrep "$prog_name") )

for ((i=0; i < ${#my_pids[@]}; i++)); do
    if [[ -d /proc/${my_pids[i]} ]]; then
        start_time=$(stat --printf=%Y /proc/${my_pids[i]})
        total_mins=$(( (the_date - start_time) / 60 ))
        if (( $total_mins >= 30 )); then
            kill -9 ${my_pids[i]}
            logger -t "Your custom message here"
        fi
    fi
done

答案 2 :(得分:0)

我曾经因为PATH和其他未自动设置的环境变量而陷入困境。

值得检查。如果不是那么评论,我将删除我的答案。

答案 3 :(得分:0)

我已经想出了怎么做。如果我使用ls的“--time-style = long-iso”参数,则以我需要的格式返回它。显然,cron对某些命令的偏好与默认用户不同。

我认为Dennis认为“ls”对于解析来说是不可靠的,但我正在使用的计算机的配置永远不会改变,所以现在它可以工作,我会保持原样。将来,我可能会按照你的方式做事。