我有一个运行smartctl
来检查硬盘运行状况的cronjob - 如果一个驱动器出现故障
cronjob是从webmin设置的,当cronjob从cronjob管理器手动运行时(按"立即运行"按钮),返回的状态为0
(OK),但是当脚本每天从cronjob运行(每个午夜)返回的状态始终是1
(一个驱动器失败)
有人能告诉我发生了什么事吗?!
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;
}
}
}
答案 0 :(得分:1)
这有两个可能的问题。
如果问题与#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
返回的路径。