【问题标题】:fread hangs when trying to ready from stdout of process opend with proc_open in PHP尝试从 PHP 中使用 proc_open 打开的进程的标准输出准备好时 fread 挂起
【发布时间】:2022-01-05 16:21:15
【问题描述】:

我正在使用 PHP 控制通过 USB 连接到 Raspberry PI 的 GSM 调制解调器,运行 PHP 7.3.31 并且:

pi@raspberrypi:~ $ uname -a
Linux raspberrypi 5.10.63-v7l+ #1459 SMP Wed Oct 6 16:41:57 BST 2021 armv7l GNU/Linux 

我能够运行此命令来连接调制解调器并与之交互:

cu -s 115200 -l /dev/ttyUSB3

当我直接从 bash 运行该命令时,我会看到以下输出:

Connected.

但是,如果我尝试使用 proc_open 连接并读取此输出,fread 会挂起:

<?php
$descriptors = [['pipe', 'r'], ['pipe', 'w'], ['file','errors.txt','a']];
$handle = proc_open('cu -s 115200 -l /dev/ttyUSB3', $descriptors, $pipes);
stream_set_blocking($pipes[1],1);
$world = fread($pipes[1],1);
var_dump($world);

我希望上面的代码打印字母“C”。

如果我将命令更改为以下内容:

cu -v

那么输出是:

cu (Taylor UUCP) 1.07
Copyright (C) 1991, 92, 93, 94, 1995, 2002 Ian Lance Taylor
This program is free software; you may redistribute it under the terms of
the GNU General Public LIcense.  This program has ABSOLUTELY NO WARRANTY.

如果我像这样从 PHP 脚本运行该命令:

<?php
$descriptors = [['pipe', 'r'], ['pipe', 'w'], ['file','errors.txt','a']];
$handle = proc_open('cu -v', $descriptors, $pipes);
stream_set_blocking($pipes[1],1);
$world = fread($pipes[1],1);
var_dump($world);

我看到了输出:

string(1) "c"

正如我所料,PHP 代码似乎没有任何问题,而且它似乎能够很好地读取 cu 命令的输出。

我可以看到错误被正确写入我的错误文件,因为当我终止脚本时,我可以看到错误文件中出现了中断信号。如果我每秒循环检查进程状态,则表明它正在运行。如果我从另一个屏幕终止该进程,它会变为未运行。

一切似乎都表明该命令正在运行并已连接,但 fread 只是挂起并且从不打印任何输出。

如果我将流设置为不阻塞,它不会挂起,但也不会返回任何输出。我也试过 fgets 和 stream_get_contents。

【问题讨论】:

  • 查看errors.txt的内容。一些输出被写入标准错误,而不是标准输出。您的 fread($pipes[1],1); 只能读取 ['pipe', 'w'] aka 标准输出。
  • 是的“我可以看到错误正在正确写入我的错误文件,因为当我终止脚本时,我可以看到错误文件中出现了中断信号”
  • 另外,由于一些奇怪的原因,管道的顺序与它们在描述符规范中传递的顺序相反。也就是说,您从写入的读取,然后写入读取的写入。如果反过来,我似乎会更有意义。

标签: php linux gsm at-command modem


【解决方案1】:

显然,这个问题的答案是“使用 Symfony”。 Symfony Process 组件似乎没有这个问题。我不知道他们在做什么不同(他们的文档说明他们在后台使用 proc_open,我还没有挖掘他们是如何做到的)但无论他们在做什么,它都有效,所以如果你发生了遇到同样的问题,那么:

composer require symfony/process

是你的朋友:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多