smartctl似乎不适用于cronjob

时间:2015-01-07 13:18:54

标签: php linux cron

我有一个运行smartctl来检查硬盘运行状况的cronjob - 如果一个驱动器出现故障

cronjob是从webmin设置的,当cronjob从cronjob管理器手动运行时(按"立即运行"按钮),返回的状态为0(OK),但是当脚本每天从cronjob运行(每个午夜)返回的状态始终是1(一个驱动器失败)

有人能告诉我发生了什么事吗?!

命令(从root运行)

php -f /var/www/cronjob.php check_hdd_health

class Cronjob_check_hdd_health {
    public function __construct(){
        if($this->check_dev('/dev/sda') && $this->check_dev('/dev/sdb')){
            $status = 0;
        }
        else{
            $status = 1;
        }

        // The status is saved in mysql with a timestamp
        echo 'Status: '.$status;
    }

    private function check_dev($dev){
        $status_ok = "=== START OF READ SMART DATA SECTION ===\nSMART overall-health self-assessment test result: PASSED";

        $output = shell_exec('smartctl -H '.$dev);

        if(strpos($output, $status_ok) !== false){
            echo "$dev OK!\n";

            return true;
        }
        else{
            echo "$dev ERROR!\n";

            return false;
        }
    }
}

enter image description here

3 个答案:

答案 0 :(得分:1)

这有两个可能的问题。

  1. 找不到smartctl的路径。
  2. 发生错误,输出未被返回。
  3. 如果问题与#1有关,则尝试添加bin的绝对路径。见下面的例子

    $output = shell_exec('/usr/bin/smartctl -H '.$dev);
    

    然而问题更可能是由输出不会回来的#2引起的。

    可以通过更改此行来解决此问题:

    $output = shell_exec('smartctl -H '.$dev);
    

    到此:

    $output = shell_exec(sprintf('smartctl -H %s 2>&1', $dev));
    

    这样做是将STDERR重定向到STDOUT,使错误通道上的输出可见。

    当然可能两者都是问题,在这种情况下,您可以将两种解决方案结合在一起。

    $output = shell_exec(sprintf('/usr/bin/smartctl -H %s 2>&1', $dev));
    

答案 1 :(得分:1)

你忽略了真正的错误,因为每次出现错误都不会将他打印到文件中,但我想这是因为你没有使用' smartctl&#的绝对路径39;命令。

mlt@slack:~$ sudo /bin/bash -c '/usr/sbin/smartctl -H /dev/sda'
smartctl 5.43 2012-06-30 r3573 [x86_64-linux-3.14.24] (local build)
Copyright (C) 2002-12 by Bruce Allen, http://smartmontools.sourceforge.net

=== START OF READ SMART DATA SECTION ===
SMART overall-health self-assessment test result: PASSED

mlt@slack:~$ sudo /bin/bash -c 'smartctl -H /dev/sda'
/bin/bash: smartctl: command not found

答案 2 :(得分:1)

sudo命令也没有执行,这让我觉得Webmin编辑的PATH中的crontab搞砸了。

您可以通过指定smartctl

来解决PATH问题
shell_exec('/usr/sbin/smartctl -H /dev/sda');

但我也会看看crontabs;系统crontab可以通过编辑/etc/crontab来检查,root crontab可以使用命令(以root身份)进行检查

crontab -e

您应该在顶部有一些定义,例如

SHELL=/bin/sh
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin
MAILTO=root

您还可以添加一些简单的shell诊断:

print "PATH is: " . getenv('PATH') . "\n";
print "Trying to locate smartctl (hoping 'which' is working)...\n";
print shell_exec('which smartctl 2>&1');
print "Trying to determine user\n";
print shell_exec('/usr/bin/whoami 2>&1');
print shell_exec('/bin/whoami 2>&1');
print shell_exec('whoami 2>&1');

然后从root尝试运行which smartctl并查看其路径是否属于上面getenv返回的路径。