幾件事情值得一提:
的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
或.basrc
文件中設置任何附加VAR)。使用crontab或通過ssh運行命令時情況並非如此。
也許,$PATH
環境變量是這樣設置的,您無權訪問ip
和其他命令。有簡單的修復此:
exech('/sbin/ip route');//if that's the correct path
或者,有在準備第二個腳本,並改變你的PHP腳本:
if (!exec('which ip'))
{//ip command not found
return exec('helper.sh '.implode(' ', $argv));//helper script
}
隨着輔助腳本看起來像這樣:
#/bin/bash
source /home/user/.bashrc
$*
其中$*
只是再次調用原始PHP腳本,只有這一次,配置文件已被加載。您可以用export PATH=$PATH:/sbin
或其他東西代替source
調用,只需按照需要的方式設置環境變量即可。
第三,最後一部分使用管道,proc_open
。這是加載配置文件並調用腳本遞歸的PHP的唯一方法:
if(!$_SERVER['FOO'])
{//where FOO is an environment variable that is loaded in the .profile/.bashrc file
$d = array(array('pipe','r'),array('pipe','w'));
$p = proc_open('ksh',$d,$pipes);
if(!is_resource($p) || end($argv) === 'CalledFromSelf')
{//if the last argument is calledFromSelf, we've been here before, and it didn't work
die('FFS');//this is to prevent deadlock due to infinite recursive self-calling
}
fwrite($pipes[0],'source /home/user/.profile'."\n");
fwrite($pipes[0],implode(' ',$argv).' CalledFromSelf'."\n");
fclose($pipes[0]);
usleep(15);//as long as you need
echo stream_get_contents($pipes[1]);
fclose($pipes[1]);
proc_close($p);
exit();
}
echo $_SERVER['FOO'].PHP_EOL;//actual script goes here, we can use the FOO env var
這是我如何解決an old question of mine在那裏我遇到了未設置
最後一點要注意的是環境變量的困難:是否運行crontab的用戶擁有需要執行什麼操作的權限?
用戶已經有權限。 – Guilgamos
@Guilgamos:也許,但是哪個用戶正在運行腳本?它屬於哪個組?它需要'sudo'來運行網絡相關的命令嗎?在* NIX系統上,這不是不可能的,畢竟如果在命令行中運行腳本, –
之後,腳本將以當前用戶權限運行。如果腳本通過crontab運行 - 具有crontab文件所屬用戶的權限。使用crontab -l -u用戶名爲某用戶顯示crontab文件 –