我想通過exec()
運行幾個命令,但我不希望任何輸出到屏幕。然而,我確實希望堅持輸出,以便我可以在腳本運行時控制詳細程度。從php exec中捕獲/禁止所有輸出,包括stderr
這裏是我的類:
<?php
class System
{
public function exec($command, array &$output = [])
{
$returnVar = null;
exec($command, $output, $returnVar);
return $returnVar;
}
}
的問題是,大多數應用程序把不相干的東西的刺激量爲stderr
,我似乎不能夠阻止。例如,下面是從通過它運行git clone
輸出:
Cloning into '/tmp/directory'...
remote: Counting objects: 649, done.
remote: Compressing objects: 100% (119/119), done.
remote: Total 649 (delta 64), reused 0 (delta 0), pack-reused 506
Receiving objects: 100% (649/649), 136.33 KiB | 0 bytes/s, done.
Resolving deltas: 100% (288/288), done.
Checking connectivity... done.
我見過的其他問題,聲稱使用輸出緩衝器可以工作,但它似乎沒有工作
<?php
class System
{
public function exec($command, array &$output = [])
{
$returnVar = null;
ob_start();
exec($command, $output, $returnVar);
ob_end_clean();
return $returnVar;
}
}
這仍然產生相同的結果。我可以通過在命令中將stderr路由到stdout來解決這個問題,但是,這不僅阻止了我與stdout和stderr的區別,這個應用程序被設計爲在Windows和Linux中運行,所以這現在是一個邪惡的混亂。
<?php
class System
{
public function exec($command, array &$output = [])
{
$returnVar = null;
// Is Windows
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
exec($command, $output, $returnVar);
return $returnVar;
}
// Is not windows
exec("({$command}) 2>&1", $output, $returnVar);
return $returnVar;
}
}
有沒有辦法分別捕獲和壓制stderr和stdout?
更新/回答樣本
在在評論@hexasoft的意見,我更新了我的方法是這樣的:
<?php
class System
{
public function exec($command, &$stdOutput = '', &$stdError = '')
{
$process = proc_open(
$command,
[
0 => ['pipe', 'r'],
1 => ['pipe', 'w'],
2 => ['pipe', 'w'],
],
$pipes
);
if (!is_resource($process)) {
throw new \RuntimeException('Could not create a valid process');
}
// This will prevent to program from continuing until the processes is complete
// Note: exitcode is created on the final loop here
$status = proc_get_status($process);
while($status['running']) {
$status = proc_get_status($process);
}
$stdOutput = stream_get_contents($pipes[1]);
$stdError = stream_get_contents($pipes[2]);
proc_close($process);
return $status['exitcode'];
}
}
這項技術開闢了更高級的選項,包括異步過程。
你*有*使用exec嗎?因爲'proc_open'可能更適合你的問題。有關詳細信息,請參閱http://php.net/manual/fr/function.proc-open.php(允許爲stdin/stdout/stderr設置專用管道) – hexasoft
不,我不必使用exec。我會探索這個並回復你。謝謝:) – DanielM
是的,這似乎很好地工作。這當然不是「更簡單」,但它絕對是我想要的。我已經更新了我的問題以顯示我對該特定方法所做的確切更改,但是我稍後將設置一些更強大的功能。你想彈出一個正確的答案,我會標記它是正確的。 – DanielM