如何解决ssh2 crate中channel.write方法无限阻塞无法返回的问题
问题原因与修复方案
你的代码卡在wait_close()的核心原因有两个:
- sudo -S 等待密码输入:
sudo -S会要求从标准输入读取密码,但你只发送了useradd命令,未提供sudo密码,导致远程进程一直等待输入无法退出。 - 未关闭标准输入流:即便提供了密码,若不明确关闭通道的标准输入,远程进程会持续等待更多输入,
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
相关产品推荐
相关产品推荐

