PHP CLI通过SSH客户端自动执行sz命令下载文件问题
借助PHP CLI在SSH客户端中自动触发sz文件下载的解决方案
问题根源
sz(zmodem协议的文件发送命令)需要直接与SSH客户端的终端环境进行交互式二进制数据传输,而PHP默认的system()、shell_exec()、passthru()函数在处理这类命令时,要么会捕获/破坏zmodem的二进制协议流,要么无法正确关联终端的tty交互环境,导致命令卡住或传输失败。
可行解决方案:使用proc_open绑定终端IO
proc_open可以手动将命令的标准输入、输出、错误流直接绑定到当前终端的tty,让sz能和SSH客户端的zmodem组件正常交互,触发下载弹窗。示例代码如下:
<?php // 确保关闭输出缓冲,避免干扰二进制流传输 if (ob_get_level() > 0) { ob_end_flush(); } // 定义IO描述符,直接关联终端的标准输入输出 $descriptorspec = [ 0 => STDIN, // 绑定终端标准输入 1 => STDOUT, // 绑定终端标准输出 2 => STDERR // 绑定终端错误输出 ]; // 执行sz命令 $process = proc_open('sz test.csv', $descriptorspec, $pipes); // 等待命令执行完成并关闭进程 if (is_resource($process)) { proc_close($process); } ?>
额外注意事项
- 服务器端必须安装
lrzsz工具包(sz命令属于该包),确保sz命令能正常执行。 - SSH客户端(如ZOC、Putty)需开启zmodem协议支持:
- ZOC:在会话设置中确认文件传输协议包含zmodem;
- Putty:需配合支持zmodem的组件(如
lrzsz+putty-zmodem插件)。
- 执行PHP脚本的用户必须拥有目标文件的读取权限。
- 不要在脚本中使用输出缓冲函数(如
ob_start()),否则会破坏zmodem的二进制传输流。
内容的提问来源于stack exchange,提问作者neoteknic
相关产品推荐
相关产品推荐

