php stderr,捕获/抑制来自php exec的所有输出,包括stderr

本文探讨如何在PHP中使用System类执行命令时,避免屏幕输出,同时保留输出供脚本控制详细级别。作者分享了proc_open函数的使用方法,以分别捕获和抑制标准输出(stdout)和标准错误(stderr),适用于跨平台环境下的Git等命令处理。
摘要由CSDN通过智能技术生成

我想通过exec()运行几个命令,但我不希望任何输出到屏幕.但是,我确实希望保持输出,以便在脚本运行时控制详细程度.

这是我的班级:

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.

我已经看到其他问题声称使用输出缓冲区可以工作,但它似乎不起作用

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中运行,所以这现在是一个不圣洁的混乱.

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在评论中的建议,我将我的方法更新为如下所示:

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'];

}

}

这种技术开辟了更多高级选项,包括异步进程.

最佳答案 命令proc_exec()允许使用管道处理exec-ed命令的文件描述符.

该函数是:resource proc_open(string $cmd,array $descriptorspec,array& $pipes [… optional parameters])

你在$cmd中给出了命令(在exec中),你给出了一个数组,描述了命令的“install”文件描述符.此数组由filedescriptor编号索引(0 = stdin,1 = stdout …)并包含类型(文件,管道)和模式(r / w …)以及文件类型的文件名.

然后,您在$pipes中获取一个文件描述符数组,可用于读取或写入(取决于所请求的内容).

您不应忘记在使用后关闭这些描述符.

请注意,读/写与生成的命令有关,而与PHP脚本无关.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用Python中的`subprocess`模块来捕获PyCharm输出窗口的内容,并使用PyQt中的`QTextEdit`来实时更新UI窗口。 以下是一个简单的示例代码: ```python import sys from PyQt5.QtWidgets import QApplication, QMainWindow, QTextEdit from PyQt5.QtCore import QThread, pyqtSignal import subprocess class ConsoleThread(QThread): output = pyqtSignal(str) def __init__(self, parent=None): super().__init__(parent) def run(self): process = subprocess.Popen(['python', '-u', 'your_script.py'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) while True: output = process.stdout.readline().decode().strip() if output: self.output.emit(output) class MainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) self.text_edit = QTextEdit() self.setCentralWidget(self.text_edit) self.console_thread = ConsoleThread() self.console_thread.output.connect(self.update_text_edit) self.console_thread.start() def update_text_edit(self, text): self.text_edit.append(text) if __name__ == '__main__': app = QApplication(sys.argv) main_window = MainWindow() main_window.show() sys.exit(app.exec_()) ``` 在上述代码中,`ConsoleThread`继承自`QThread`,用于在后台运行PyCharm输出窗口的内容。`run`方法使用`subprocess`模块启动一个子进程并捕获输出。如果输出不为空,则通过`output`信号将其发送给UI线程。 在`MainWindow`中,我们创建了一个`QTextEdit`用于显示PyCharm输出窗口的内容。我们还创建了一个`ConsoleThread`并连接了其`output`信号到`update_text_edit`槽函数。在`update_text_edit`中,我们使用`append`方法将新的文本追加到`QTextEdit`中。 最后,我们创建了一个`QApplication`并显示`MainWindow`。当应用程序运行时,`ConsoleThread`将在后台捕获并发送PyCharm输出窗口的内容,而`MainWindow`将实时更新`QTextEdit`中的文本。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值