go - 在golang ssh session 关闭中将EOF作为错误

标签 go ssh

我正在使用“ssh”golang 模块,我想知道我是否实现了它(或尝试)。
session.Close() 中的“EOF”是否是预期的错误?在我在网上看到的示例中,没有人检查 session.Close() 错误。这是我应该忽略或处理的事情吗?
据我所知,服务器也不会出现错误。
我想知道我是否没有正确执行命令,或者没有正确读取缓冲区。

这是我的代码:

package main

import (
    "bytes"
    "fmt"
    "strings"

    "golang.org/x/crypto/ssh"
)

func main() {
    sshConfig := &ssh.ClientConfig{
        User: “my_username”,
        Auth: []ssh.AuthMethod{
            ssh.Password(“my password”),
        },
        HostKeyCallback: ssh.InsecureIgnoreHostKey(),
    }
    connection, err := ssh.Dial("tcp", "localhost:22", sshConfig)
    if err != nil {
        fmt.Printf("Failed to dial: %s\n", err)
        return
    }

    defer func() {
        if err := connection.Close(); err != nil {
            fmt.Println("Received an error closing the ssh connection: ", err)
        } else {
            fmt.Println("No error found closing ssh connection")
        }
    }()

    session, err := connection.NewSession()
    if err != nil {
        fmt.Printf("Failed to create session: %s\n", err)
        return
    }

    defer func() {
        if err := session.Close(); err != nil {
            fmt.Println("Received an error closing the ssh session: ", err)
        } else {
            fmt.Println("No error found closing ssh session")
        }
    }()
    fmt.Println("created session")
    var stdOut bytes.Buffer
    var stdErr bytes.Buffer

    session.Stdout = &stdOut
    session.Stderr = &stdErr
    err = session.Run("pwd")
    fmt.Println("Executed command")

    fmt.Println("Command stdOut is:", strings.TrimRight(stdOut.String(), "\n"), " --- stdError is:", strings.TrimRight(stdErr.String(), "\n"))

}

我得到的输出是:
$ go run main.go
created session
Executed command
Command stdOut is: /Users/my_username  --- stdError is: 
Received an error closing the ssh session:  EOF
No error found closing ssh connection
$ 

有什么建议吗?

最佳答案

这似乎类似于 golang/go/issue 31401 (然后指issue 32453:“x/crypto/ssh :在调用 session.Run() 之后运行 session.Wait() 的语义,当发送 EOF 消息时")

The error is returned because the session has already been closed (by Run()).
The SSH connection leaks because it is never closed — the client object returned from Dial() is discarded, but that's the object that needs to be closed to clean up the underlying TCP connection.

As an aside, this seems to be a subtle API to use correctly.
The session can be closed asynchronously at any time by the other side, and so it's always possible for correctly-written code to get an EOF from Close()



所以你可能想测试那个特定的错误,并在你的 defer 函数中忽略它。

关于go - 在golang ssh session 关闭中将EOF作为错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60879023/

相关文章:

关于忽略上下文取消功能的 vert 警告

file - 如何将结构作为二进制数据写入golang中的文件?

php - 是否可以在不创建 .ssh 目录的情况下执行 ssh 命令?

ssh - 如何在cPanel中为特定子域的用户提供SSH访问权限

windows - Eclipse SSH Remote System Explorer 在 Windows 上是否损坏?

ssh - 许多SSH登录均可使用

go - 我怎样才能避免死锁

go - 使用 Go 使用 http/2 连接到 Alexa 语音服务时遇到问题

go - 什么是快路径、慢路径、热路径

c++ - 如何在命令中传递多个参数以使用 C/C++ 和 SSH 在远程 Linux 机器上执行 exe