PHP通过SSH执行命令时如何正常输出多页分页返回结果
问题原因
华为交换机默认开启终端分页输出,单页输出满屏后会暂停,等待用户按空格触发后续内容输出。原有代码仅执行了查询命令,未处理分页交互逻辑,SSH流会一直阻塞等待翻页指令,无法读到流结束标识,最终导致页面无限加载。
解决方案
优先选择关闭会话分页的方案,兼容性好、实现简单,无需匹配不同版本的分页提示符。
方案1:执行查询前临时关闭当前会话分页(推荐)
华为交换机提供screen-length 0 temporary命令,可临时关闭当前SSH会话的分页功能,所有命令输出会一次性返回,不会触发翻页暂停,命令仅对当前登录会话生效,不会修改设备的永久配置。
修改后的完整代码如下:
$connection = ssh2_connect($ip, 22); ssh2_auth_password($connection, 'login', 'password'); // 临时关闭当前会话分页 $pre_stream = ssh2_exec($connection, "screen-length 0 temporary"); stream_set_blocking($pre_stream, true); $pre_out = ssh2_fetch_stream($pre_stream, SSH2_STREAM_STDIO); // 等待前置命令执行完成 stream_get_contents($pre_out); fclose($pre_stream); // 执行业务查询命令 $stream = ssh2_exec($connection, $ssh_input); stream_set_blocking($stream, true); $stream_out = ssh2_fetch_stream($stream, SSH2_STREAM_STDIO); echo "<pre>"; // 转义特殊字符,避免返回内容包含HTML标签导致页面渲染异常 echo htmlspecialchars(stream_get_contents($stream_out)); echo "</pre>"; // 释放连接资源 fclose($stream_out); fclose($stream); ssh2_disconnect($connection);
方案2:交互读取流自动响应分页(适配特殊版本设备)
如果设备版本不支持临时关闭分页的命令,可通过非阻塞循环读取流内容,检测到分页提示符时自动发送空格翻页,直到读取到命令结束提示符为止。
参考实现代码:
$connection = ssh2_connect($ip, 22); ssh2_auth_password($connection, 'login', 'password'); $stream = ssh2_exec($connection, $ssh_input); // 设置非阻塞模式 stream_set_blocking($stream, false); $stream_out = ssh2_fetch_stream($stream, SSH2_STREAM_STDIO); $full_output = ''; $timeout = 30; // 30秒超时,避免异常场景下永久循环 $start_ts = time(); while (time() - $start_ts < $timeout) { $chunk = fread($stream_out, 4096); if (!empty($chunk)) { $full_output .= $chunk; // 匹配华为设备分页提示符,发送空格翻页 if (strpos($full_output, '---- More ----') !== false) { fwrite($stream, ' '); // 清除输出中的分页提示字符 $full_output = str_replace('---- More ----', '', $full_output); } // 匹配命令执行结束的提示符,需根据自身设备的主机名规则调整正则 if (preg_match('/<[\w-]+>[\s]*$|\[[\w-]+\][\s]*$/', $full_output)) { break; } } usleep(100000); // 休眠100ms降低CPU占用 } echo "<pre>"; echo htmlspecialchars($full_output); echo "</pre>"; fclose($stream_out); fclose($stream); ssh2_disconnect($connection);
注意事项
- 输出到网页前必须使用
htmlspecialchars对返回内容做转义,避免设备返回内容包含HTML/JS代码引发XSS风险或页面排版错乱。 - 方案2中的提示符匹配规则需要根据实际设备的配置调整,比如自定义主机名包含特殊字符时需要同步修改正则表达式。
- 若使用PHP7及以下版本,代码中字符串匹配逻辑可直接使用
strpos实现,无需依赖PHP8+专属的str_contains函数。
内容的提问来源于stack exchange,提问作者Narmo
相关产品推荐
相关产品推荐

