Golang中crypto/ssh:Session.Wait()在连接结束时也会返回吗?

Golang中crypto/ssh:Session.Wait()在连接结束时也会返回吗? Session.Wait() 是否会在 SSH 主连接结束时返回?

在 Godoc 中写道

Wait 等待远程命令退出。

如果命令运行正常,复制 stdin、stdout 和 stderr 没有问题,并以零退出状态退出,则返回的错误为 nil。

如果远程服务器没有发送退出状态,则返回 *ExitMissingError 类型的错误。如果命令未成功完成或被信号中断,则错误类型为 *ExitError。对于 I/O 问题,可能会返回其他错误类型。

但尚不清楚即使 SSH 连接结束,它是否仍会保持阻塞状态


更多关于Golang中crypto/ssh:Session.Wait()在连接结束时也会返回吗?的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang中crypto/ssh:Session.Wait()在连接结束时也会返回吗?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


是的,Session.Wait() 会在 SSH 主连接结束时返回。当 SSH 连接意外断开时,Wait() 方法会检测到连接关闭并返回相应的错误,而不是无限期阻塞。

根据 crypto/ssh 包的实现,Session.Wait() 会监控底层 SSH 连接的状态。如果连接在远程命令执行完成前被关闭,Wait() 会返回一个错误,通常是与连接断开相关的 I/O 错误。

以下是一个示例,演示了连接中断时 Wait() 的行为:

package main

import (
    "fmt"
    "golang.org/x/crypto/ssh"
    "log"
    "net"
    "time"
)

func main() {
    config := &ssh.ClientConfig{
        User: "username",
        Auth: []ssh.AuthMethod{
            ssh.Password("password"),
        },
        HostKeyCallback: ssh.InsecureIgnoreHostKey(),
    }
    
    // 建立 SSH 连接
    conn, err := ssh.Dial("tcp", "host:22", config)
    if err != nil {
        log.Fatal("连接失败: ", err)
    }
    defer conn.Close()
    
    // 创建会话
    session, err := conn.NewSession()
    if err != nil {
        log.Fatal("创建会话失败: ", err)
    }
    
    // 启动一个长时间运行的命令
    err = session.Start("sleep 30")
    if err != nil {
        log.Fatal("启动命令失败: ", err)
    }
    
    // 在单独的 goroutine 中等待命令完成
    done := make(chan error, 1)
    go func() {
        done <- session.Wait()
    }()
    
    // 模拟连接中断:主动关闭连接
    time.Sleep(2 * time.Second)
    conn.Close()
    
    // 等待 Wait() 返回
    waitErr := <-done
    if waitErr != nil {
        fmt.Printf("Wait() 返回错误: %v\n", waitErr)
    } else {
        fmt.Println("命令正常退出")
    }
}

在这个示例中:

  1. 启动一个会运行 30 秒的 sleep 命令
  2. 在命令执行过程中主动关闭 SSH 连接
  3. Session.Wait() 会检测到连接关闭并返回错误

典型输出可能是:

Wait() 返回错误: ssh: connection lost

这表明当 SSH 连接结束时,Session.Wait() 确实会返回,而不是永久阻塞。返回的错误类型通常是 *ssh.ExitError 或与连接相关的 I/O 错误,具体取决于连接中断的时机和方式。

回到顶部