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

如何改进Renci SSH.NET的SSH函数,取消延迟并获取完整输出?

解决Renci SSH.NET ShellStream命令输出不完整的问题(替代Thread.Sleep的方案)

你当前用ShellStream加固定Thread.Sleep的方式不可靠——命令执行时长不稳定,延迟设短了输出不全,设长了浪费时间。下面给两个更可靠的方案:

方案1:用RunCommand替代ShellStream(推荐,单命令场景)

Renci SSH.NET提供了SshClient.RunCommand方法,专门用于执行单条非交互式命令,它会自动等待命令执行完成后返回完整输出,完全不需要手动加延迟。

替换后的代码:

Public Function SendSSHCommand(ByVal command As String) As String
    Dim host As String = "10.0.1.77"
    Dim port As Integer = 228
    Dim user As String = "User11"
    Dim password As String = "pass11"

    Dim result As String = String.Empty

    Dim connectionInfo As New ConnectionInfo(host, port, user, New PasswordAuthenticationMethod(user, password))

    Using client As New SshClient(connectionInfo)
        Try
            client.Connect()
            Dim cmd As SshCommand = client.RunCommand(command)
            ' 合并标准输出和错误输出
            result = cmd.Result & If(String.IsNullOrEmpty(cmd.Error), "", vbCrLf & "Error: " & cmd.Error)
            client.Disconnect()
        Catch ex As Exception
            result = "Error: " & ex.Message
        End Try
    End Using

    Return result
End Function

方案2:必须用ShellStream的场景(交互式操作)

如果需要执行交互式命令(比如多命令依赖、需要输入交互内容),可以通过检测服务器命令提示符判断命令是否执行完成,替代固定延迟。

示例代码:

Public Function SendSSHCommandWithShellStream(ByVal command As String) As String
    Dim host As String = "10.0.1.77"
    Dim port As Integer = 228
    Dim user As String = "User11"
    Dim password As String = "pass11"
    ' 根据服务器实际提示符修改,比如"$ "、"# "或完整的"user@server:~$ "
    Dim prompt As String = "$ "
    Dim timeoutMs As Integer = 10000 ' 10秒超时

    Dim result As String = String.Empty

    Dim connectionInfo As New ConnectionInfo(host, port, user, New PasswordAuthenticationMethod(user, password))

    Using client As New SshClient(connectionInfo)
        Try
            client.Connect()

            Using shell As ShellStream = client.CreateShellStream("custom", 80, 24, 800, 600, 1024)
                Dim reader As New StreamReader(shell)
                Dim writer As New StreamWriter(shell)
                writer.AutoFlush = True

                ' 读取初始提示符,确认Shell已就绪
                Dim initialOutput As String = reader.ReadToEnd()
                If Not initialOutput.Contains(prompt) Then
                    result = "Error: 无法识别服务器提示符"
                    Return result
                End If

                ' 发送命令
                writer.WriteLine(command)

                ' 循环读取输出直到出现提示符或超时
                Dim startTime As DateTime = DateTime.Now
                Dim outputBuilder As New StringBuilder()
                Do While (DateTime.Now - startTime).TotalMilliseconds < timeoutMs
                    If shell.DataAvailable Then
                        Dim line As String = reader.ReadLine()
                        If line Is Nothing Then Exit Do
                        outputBuilder.AppendLine(line)
                        ' 检测到提示符,说明命令执行完成
                        If line.Contains(prompt) Then
                            ' 截断最后的提示符(按需调整)
                            Dim finalOutput As String = outputBuilder.ToString()
                            result = finalOutput.Substring(0, finalOutput.LastIndexOf(prompt))
                            Exit Do
                        End If
                    Else
                        ' 短暂休眠避免CPU占用过高
                        Thread.Sleep(100)
                    End If
                Loop

                ' 判断是否超时
                If result = String.Empty Then
                    result = "Error: 命令执行超时"
                End If

                shell.Close()
            End Using

            client.Disconnect()
        Catch ex As Exception
            result = "Error: " & ex.Message
        End Try
    End Using

    Return result
End Function

注意事项

  • 优先用方案1,RunCommand是SSH.NET为单命令场景设计的API,逻辑简洁且可靠。
  • 方案2中,提示符必须和服务器实际显示的一致,如果服务器提示符随用户/路径变化,需要动态调整prompt变量。
  • 超时时间可根据命令实际耗时灵活调整,避免误判长时间运行的合法命令。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 17:40:02