【问题标题】:Bash script and cron anomalyBash 脚本和 cron 异常
【发布时间】:2009-12-15 04:44:58
【问题描述】:

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

基本上,脚本(如下)获取我的程序的 PID,并从 /proc/ 目录中的条目中获取它的创建日期/时间。然后它从系统中获取当前日期/时间,并使用“date”命令将这两个值转换为自 1970 年以来的秒数,最后减去这两个值。这通常以总共 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”,后者抛出所有计算。

有什么想法吗?谢谢。

【问题讨论】:

  • 刚刚检查了一下,似乎第 6 列是日期(awk '{print $6, $7}' 位)返回为“Dec 14”而不是“2009-12-14”正如我所预料的那样。仍然不确定如何绕过它。

标签: linux bash cron


【解决方案1】:

首先从不解析ls的输出,阅读THIS以了解原因。接下来,您的脚本可以通过使用pgrep 来大大改进,而不是使用 awk 从 'ps aux' 上的 grep 解析 PID。此外,在您返回多个 PID 的情况下,您的脚本会严重中断。最后,在编写 shell 脚本时,尽量不要使用大写字母作为变量名;该约定保留给您 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】:

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

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

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

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

    【讨论】:

      【解决方案3】:

      我曾经被 PATH 和其他未自动设置的环境变量所困扰。

      值得一试。如果不是这样,请发表评论,我将删除我的答案。

      【讨论】:

      • 我试图避开环境变量,我只使用绝对路径。我不认为脚本依赖于这样的东西。还是谢谢。
      【解决方案4】:

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

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

      【讨论】:

      猜你喜欢
      • 2011-08-15
      • 2013-03-14
      • 1970-01-01
      • 1970-01-01
      • 2012-10-22
      • 1970-01-01
      • 1970-01-01
      • 2011-08-10
      • 2013-11-26
      相关资源
      最近更新 更多