我有一个PHP应用程序,它通过SSH登录到本地机器,启动shellscript并将该脚本的输出实时打印回浏览器(通过保持页面加载(。
但是,当 shellscript 命中sudo service apache2 reload > /dev/null
1024 字节看似随机的内存被转储并在脚本正常完成时中止输出。
当连接最终终止(例如通过终止它(时,屏幕上会吐出一些额外的随机内容,具体取决于连接保持打开状态的时间。
执行 PHP 脚本只是读取 SSH 连接的 stdout,直到发生一些中止/终止事件。除此之外,它还将ANSI颜色代码转换为HTML <span>
:
stream_set_blocking($this->stdo, true);
fwrite($this->stdo, $cmd . "'n"); // write command to start running shellscript
$buf = '';
do
{
$buf = fread($this->stdo, 256);
if ($ansicolor)
echo $this->ansicolor($buf); // color codes are translated to HTML here
else
echo $buf;
flush();
ob_flush();
}
while (strpos($buf, '$') === false);
flush();
ob_flush();
对于所有与安全相关的人:PHP 正在登录一个普通用户,该用户仅对该命令具有"NOPASSWD"sudo。
我可以告诉sudo
调用导致了问题,因为我的脚本经常通过echo
输出正在发生的事情,这显示正常。
另外,我不想在重新加载失败并吐出实际有用的错误的情况下将 stderr 管道带走。
相关内容的已安装版本:
- PHP
5.3.3-7+squeeze17 with Suhosin-Patch (cli) (built: Aug 23 2013 15:06:16)
我需要 PHP 5.3,因为遗留应用程序无法处理较新版本。 - libssh2-php
0.11.0-2.1
- OpenSSL
1.0.1e-2+deb7u7
(https://www.debian.org/security/2014/dsa-2896( - openssh-server
1:6.0p1-4+deb7u1
如何解决此问题以不再转储随机内存?
您在屏幕上看不到"内存转储"。 您看到的是 stderr 上 service
命令的输出。 它通常在屏幕上看起来像这样:
* Reloading web server config apache2 [OK]
[OK] 消息正在进行一些 ANSI 格式设置,这将填充 1024 字节的其余部分。
如果你想避免"垃圾",同时仍然看到错误,你想去掉所有的ANSI格式。 像这样:
service apache2 reload >/dev/null 2> >(sed -r "s/'x1B'[([0-9]{1,3}((;[0-9]{1,3})*)?)?[m|K]//g")