我想通过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