如何使ssh2_exec输出与Linux Shell中的格式一致?
解决Windows PHP通过SSH执行Linux脚本获取格式化输出的问题
问题核心
通过Windows上的PHP ssh2_exec 执行Linux服务器的PHP脚本时,得到的是无格式的整串文本,但直接在Linux终端运行该脚本却能得到带换行、列表的格式化输出。这是因为ssh2_exec默认使用非交互式shell,目标脚本可能根据是否为交互式环境调整了输出格式,或者缺少终端环境触发的格式化逻辑。
解决方案
1. 为SSH会话请求伪终端(PTY)
通过ssh2_request_pty()为SSH会话分配伪终端,让远程脚本认为是在终端环境中运行,从而输出格式化内容:
$connection_portalemis = ssh2_connect('192.168.34.77', 22); ssh2_auth_password($connection_portalemis, 'usr', 'pwd'); // 请求伪终端,模拟交互式终端环境 ssh2_request_pty($connection_portalemis); $controllikd4 = ssh2_exec($connection_portalemis, '/usr/local/bin/php /var/www/html/php/kd4check_new/controllikd4.php'); stream_set_blocking($controllikd4, true); $controlliSOA = stream_get_contents($controllikd4); // 转换Linux换行符为Windows兼容的\r\n(若需要本地显示) $controlliSOA = str_replace("\n", "\r\n", $controlliSOA);
2. 使用交互式Shell会话
如果请求PTY无效,可以用ssh2_shell()创建完整的交互式Shell,模拟直接在终端操作的场景:
$connection_portalemis = ssh2_connect('192.168.34.77', 22); ssh2_auth_password($connection_portalemis, 'usr', 'pwd'); // 创建交互式Shell,指定终端类型 $shell = ssh2_shell($connection_portalemis, 'xterm'); // 发送执行脚本的命令,末尾加换行符触发执行 fwrite($shell, '/usr/local/bin/php /var/www/html/php/kd4check_new/controllikd4.php' . PHP_EOL); // 等待脚本执行完成(根据实际执行时间调整sleep时长) sleep(3); stream_set_blocking($shell, true); $controlliSOA = stream_get_contents($shell); fclose($shell); // 过滤掉Shell提示符等无关内容(示例,需根据实际提示符调整) $controlliSOA = preg_replace('/^\S+@\S+:~\$\s+/m', '', $controlliSOA); $controlliSOA = str_replace("\n", "\r\n", $controlliSOA);
3. 修改目标脚本强制输出格式化内容
如果上述方法无法解决,直接修改Linux上的controllikd4.php,让它忽略环境变量,始终输出格式化内容:
- 检查脚本中是否有
posix_isatty()或终端类型检测逻辑,注释掉相关判断; - 添加命令行参数(如
--format),当脚本接收到该参数时强制输出格式化文本:
然后在Windows的PHP中执行命令时加上参数:// 在controllikd4.php开头添加 $forceFormat = in_array('--format', $argv); // 后续输出逻辑中,若$forceFormat为true则输出格式化内容$controllikd4 = ssh2_exec($connection_portalemis, '/usr/local/bin/php /var/www/html/php/kd4check_new/controllikd4.php --format');
内容的提问来源于stack exchange,提问作者Fabio
相关产品推荐
相关产品推荐

