提问人:Alexandr Suleymanov 提问时间:4/23/2015 最后编辑:Alexandr Suleymanov 更新时间:2/3/2020 访问量:943
FEOF 生成无限循环
feof generates infinite loop
问:
所以我做了一件简单的事情,首先我通过ssh2_exec执行命令(成功验证后),然后在变量中读取答案。我的代码如下(未进行身份验证)
try {
$stdout_stream = ssh2_exec($this->connection, $_cmd);
$stderr_stream = ssh2_fetch_stream($stdout_stream, \SSH2_STREAM_STDERR);
} catch (Exception $e) {
$std_output = $e->getMessage();
return false;
}
$output = "";
while (!feof($stdout_stream)) {
$output .= fgets($stdout_stream, 4096);
}
while (!feof($stderr_stream)) {
$output .= fgets($stderr_stream, 4096);
}
fclose($stdout_stream);
fclose($stderr_stream);
return $output;
例如,我尝试执行这样的cmd:
sudo service httpd stop && sudo service httpd start
因此,当命令执行良好时,一切都很好,响应是
关闭 httpd: [ OK ]启动 httpd: [ OK ]
但是当我尝试在没有 sudo 的情况下执行这样的命令时
service httpd stop && service httpd start
我知道服务器说“找不到命令”或类似的东西,但我无法收到此错误,此脚本无限执行。
我试图以这种方式(或其他类似的方式)重写我的代码
$dataString = fgets($stdout_stream);
if($dataString == "\n" || $dataString == "\r\n" || $dataString == "") {
//var_dump("Empty line found.");
}
if($dataString === false && !feof($stdout_stream)) {
//var_dump("not string");
} elseif($dataString === false && feof($stdout_stream)) {
//var_dump("We are at the end of the file.\n");
break;
} else {
//else all is good, process line read in
$output .= $dataString;
}
}
但结果是一样的。
所以问题是我们不能事先说出是什么原因导致了无限循环或.$stdout_stream
$stderr_stream
我正在使用 PHP 5.3。
答:
0赞
Alexandr Suleymanov
4/24/2015
#1
我决定相信我的服务器有足够的 ~2 秒来检查是否存在错误。以防万一,为 secod 循环设置最大时间。所以我的代码如下。它的执行力比我想要的要多......
try {
$stdout_stream = ssh2_exec($this->connection, $_cmd);
$stderr_stream = ssh2_fetch_stream($stdout_stream, \SSH2_STREAM_STDERR);
} catch (Exception $e) {
$std_output = $e->getMessage();
return false;
}
$output = "";
$start_time = time();
$max_time = 2; //time in seconds
while(((time()-$start_time) < $max_time)) {
$output .= fgets($stderr_stream, 4096);
}
if(empty($output)) {
$start_time = time();
$max_time = 10; //time in seconds
while (!feof($stdout_stream)) {
$output .= fgets($stdout_stream, 4096);
if((time()-$start_time) > $max_time) break;
}
}
fclose($stdout_stream);
fclose($stderr_stream);
return $output;
0赞
Jared Brandt
2/3/2020
#2
男孩,我很高兴我找到了这个!我遇到了同样的问题。我最终以这种方式解决了它。
而不是:
while (!feof($stdout_stream)) {
$output .= fgets($stdout_stream, 4096);
}
while (!feof($stderr_stream)) {
$output .= fgets($stderr_stream, 4096);
}
执行此操作:
while (!feof($stdout_stream) || !feof($stderr_stream)) {
$output_stdout .= fgets($stdout_stream, 4096);
$output_stderr .= fgets($stderr_stream, 4096);
}
技术细节超出了我的范围,但似乎两个描述符同时关闭,而不是一次关闭一个。
评论
fgets($stdout_stream)