You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决ssh2 crate中channel.write方法无限阻塞无法返回的问题

问题原因与修复方案

你的代码卡在wait_close()的核心原因有两个:

  1. sudo -S 等待密码输入:sudo -S会要求从标准输入读取密码,但你只发送了useradd命令,未提供sudo密码,导致远程进程一直等待输入无法退出。
  2. 未关闭标准输入流:即便提供了密码,若不明确关闭通道的标准输入,远程进程会持续等待更多输入,wait_close()会一直阻塞。

修正后的代码示例

// 创建会话通道
let mut channel = self.0.channel_session()?;

// 构造sudo命令(保留换行符)
let user_add = format!("sudo -S {} {}\n", utils::USER_ADD, username);
channel.write(user_add.as_bytes())?;

// 发送sudo密码(替换为实际密码,结尾加换行)
let sudo_password = "your_sudo_password\n";
channel.write(sudo_password.as_bytes())?;

// 刷新缓冲区,确保所有数据发送到服务器
channel.flush()?;

// 关闭通道写入端,告知远程进程无更多输入
channel.eof()?;

// 读取stderr输出(可选,用于验证sudo执行状态)
let mut stderr = channel.stderr();
let mut response = String::new();
stderr.read_to_string(&mut response)?;

// 等待通道关闭并获取退出状态
channel.wait_close()?;
let exit_status = channel.exit_status()?;

关键修复点

  • 补充sudo密码:必须在命令后发送sudo密码,且结尾加换行符,让sudo识别输入结束。
  • 调用channel.eof():关闭通道写入端,告知服务器本地不再发送数据,触发远程进程处理完输入后退出。
  • 优先读取输出:先读取stderr/stdout内容,避免缓冲区满导致远程进程阻塞。

内容的提问来源于stack exchange,提问作者akhildevelops

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 16:15:38