我有一个执行一些shell命令的PHP脚本。
我手动执行它。它工作得非常好。
但是在我使用crontab执行之后,缺少一些shell命令的结果。
这是2个命令。
ip route
iptables -t nat -L | grep 8800
这是一个示例PHP代码。
#!/usr/bin/php -q
<?
$route = exec('ip route');
$iptable = exec('iptables -t nat -L | grep 8800');
echo $route;
echo $iptables;
?>
上面的代码适用于手动执行但不适用于crontab。
我发现一些命令对两者都有效。例如
ifconfig eth0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}'
cat /tmp/example | grep test
对此问题有任何想法,并提前感谢您。
答案 0 :(得分:4)
值得注意的一些事情:
exec
功能的签名是
string exec ( string $command [, array &$output [, int &$return_var ]] )
要获得命令的完整输出,您必须像这样调用它:
$output = array();//declare in advance is best because:
$lastLine = exec('ip route', $status, $output);//signature shows reference expected
print_r($output);//full output, array, each index === new line
echo PHP_EOL, 'The command finished ', $status === 0 ? 'well' : 'With errors: '.$status;
您正在使用exec
命令,就好像它是passthru
一样,在您的情况下可能值得一看:
命令结果的最后一行。如果您需要执行命令并将命令中的所有数据直接传回而不受任何干扰,请使用the passthru() function。
重要的是,当您手动运行该命令时,它可以访问您登录时加载的所有环境变量(以及.profile
或{{中设置的任何其他变量1}}文件)。使用crontab或ssh运行命令时不是这种情况
也许,.basrc
环境变量设置为,您无法访问$PATH
和其他命令。有一些简单的解决方法:
ip
或者,准备好第二个脚本,并将PHP脚本更改为:
exech('/sbin/ip route');//if that's the correct path
帮助程序脚本如下所示:
if (!exec('which ip'))
{//ip command not found
return exec('helper.sh '.implode(' ', $argv));//helper script
}
#/bin/bash
source /home/user/.bashrc
$*
只是再次调用原始PHP脚本,只是这次,已经加载了配置文件。您可以使用$*
或其他内容替换source
来电,并按照您需要的方式设置环境变量。
第三部分,最后一部分使用管道,proc_open
。它是一种仅支持PHP的方式来加载配置文件并以递归方式调用脚本:
export PATH=$PATH:/sbin
这就是我解决an old question of mine的问题,我遇到了未设置环境变量的困难
最后要注意的是:运行crontab的用户是否具有执行所需操作所需的权限?
答案 1 :(得分:0)
注意用户运行脚本的内容。可能是用户(您添加了crontab任务)没有获得足够的权限。