SSH.NET的RunCommand/Execute命令挂起,Putty手动连接可正常执行命令
SSH.NET执行命令挂起的问题排查与解决
使用SSH.NET的RunCommand或CreateCommand.Execute执行命令时出现挂起,但Putty手动连接可正常操作,通常是以下几种原因导致,对应解决方法如下:
1. 异步调用.Result引发的死锁
第一个代码示例中直接使用.Result同步获取异步操作结果,在部分同步上下文(如UI线程)中会触发死锁。建议改用异步调用方式:
using (var duclient = new SshClient("ipaddress", 22, "admin", "admin")) { duclient.Connect(); var commandResult = await duclient.RunCommandAsync("show outlets"); Console.WriteLine(commandResult.Result); duclient.Disconnect(); }
若必须同步执行,可通过脱离当前同步上下文避免死锁:
using (var duclient = new SshClient("ipaddress", 22, "admin", "admin")) { duclient.Connect(); string poweroff = Task.Run(() => duclient.RunCommandAsync("show outlets")).GetAwaiter().GetResult(); Console.WriteLine(poweroff); duclient.Disconnect(); }
2. 未读取输出导致缓冲区阻塞
第二个代码示例中调用Execute()后未读取命令输出,当目标设备返回的输出填满SSH.NET的内部缓冲区时,会导致命令执行挂起。必须主动读取Result或Output属性:
using (var duclient = new SshClient("ipaddress", 22, "admin", "admin")) { duclient.Connect(); SshCommand command = duclient.CreateCommand("show outlets"); command.Execute(); // 必须读取输出,释放缓冲区 Console.WriteLine(command.Result); duclient.Disconnect(); }
3. 适配定制化CLI设备(如PDU、交换机)
很多嵌入式设备的命令行并非标准POSIX Shell,RunCommand依赖的exec通道无法正常工作,需要模拟Putty的交互流程,使用ShellStream发送命令并读取输出:
using (var duclient = new SshClient("ipaddress", 22, "admin", "admin")) { duclient.Connect(); // 创建ShellStream,参数可根据设备调整 using (var shell = duclient.CreateShellStream("xterm", 80, 24, 800, 600, 1024)) { // 读取登录后的初始提示符 string initialOutput = shell.Read(); Console.WriteLine(initialOutput); // 发送命令,需匹配设备的命令结束符(通常是换行符) shell.WriteLine("show outlets"); // 读取命令输出,添加超时逻辑避免无限等待 var stopwatch = System.Diagnostics.Stopwatch.StartNew(); StringBuilder commandOutput = new StringBuilder(); // 假设设备的命令提示符为"admin>",以此判断命令执行完成 while (stopwatch.ElapsedMilliseconds < 5000) { if (shell.DataAvailable) { string chunk = shell.Read(); commandOutput.Append(chunk); if (chunk.Contains("admin>")) { break; } } System.Threading.Thread.Sleep(100); } Console.WriteLine(commandOutput.ToString()); } duclient.Disconnect(); }
4. 检查目标设备的SSH通道配置
部分设备默认禁用了exec通道(RunCommand依赖此通道),仅允许shell通道连接。可通过Putty开启日志功能,对比手动操作与代码执行的SSH交互流程,确认设备支持的通道类型。
内容的提问来源于stack exchange,提问作者cool_viju
相关产品推荐
相关产品推荐

