你正在使用的Go版本是什么( go version
)?
$ go version
go version go1.14.1 darwin/amd64
$
这个问题在最新版本的发布中是否会重现?
是的,我相信我正在使用最新的稳定版本。
你正在使用什么操作系统和处理器架构( go env
)?go env
输出
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/my_username/Library/Caches/go-build"
GOENV="/Users/my_username/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/my_username/Learn/go_learn"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/my_username/Learn/go_learn/src/my_stuff/ssh_test/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/17/vmjmghsj28d4lzrx7mqshr9r0000gp/T/go-build681325874=/tmp/go-build -gno-record-gcc-switches -fno-common"
$
你做了什么?
我的程序连接到一个ssh服务器(在这个例子中只是我的笔记本电脑),发出一个ssh命令,关闭SSH会话和连接:
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"))
}
你期望看到什么?
在session.close()中,我期望看到'nil'作为输出,而不是任何错误。
你看到了什么?
我在session.Close()中得到了EOF错误。在论坛上查看了其他已解决的问题( #16194 )后,似乎在Run()结束时得到EOF是合理的。然而,对于Close()来说,将其作为错误返回而不是返回nil似乎是奇怪的。
可能是我没有正确处理缓冲区管理、执行命令或关闭它。但是上面粘贴的代码来自在线示例,看起来像是工作模式。
EOF在close时是可以处理的,但要非常清楚和精确,我认为Close()应该返回nil。EOF似乎也不像是一个错误。
7条答案
按热度按时间zvms9eto1#
你好,
这似乎是一个问题,而不是关于实现中bug的报告(至少目前还没有)。
与许多项目不同,Go项目不使用GitHub Issues进行一般讨论或提问。GitHub Issues仅用于跟踪bug和proposals。
提问请参考:
#general
频道是一个很好的起点。请在上述论坛之一提问。
(摘自https://golang.org/wiki/Questions)
btxsgosb2#
你好,
我在stackoverflow上提出了一个问题:https://stackoverflow.com/questions/60879023/getting-eof-as-error-in-golang-ssh-session-close
然而,这被认为是一个bug。
efzxgjgh3#
听起来不错。重新开放。
@FiloSottile@hanwen
ia2d9nvy4#
看起来这是在运行OpenSSH时发生的情况。你能提供一个Go SSH针对自身的重现案例吗?
我之所以这么问,是因为可能有一些配置在SSH服务器上,如果会话结束,就会断开连接。
6qqygrtg5#
有没有一个Go SSH服务器的示例,我可以尝试运行或者它可能对你进行调试有帮助?我从来没有运行过SSH服务器,通常针对另一个我可以ssh到的主机进行测试(我猜通常运行OpenSSH)。
我尝试了这个 https://gist.github.com/jpillora/b480fde82bff51a06238 ,但它在我的电脑上打开bash会话时遇到了麻烦。不确定是否是权限问题或其他问题。
tquggr8v6#
我遇到了同样的问题
go版本:go1.16.6 linux/amd64
a0x5cqrl7#
我注意到*ssh.channel数据类型的Close方法也存在类似的问题(返回了无意义的io.EOF)。
可能的原因是从channel.Close到channel.sendMessage到channel.writePacket,如果已经发生了关闭,它会返回EOF,这表明应用程序中存在错误,但在这种情况下,EOF是错误的错误。
https://cs.opensource.google/go/x/crypto/+/32db7946:ssh/channel.go;l=208;drc=32db794688a5a24a23a43f2a984cecd5b3d8da58
[更新:经过进一步调查,sentClose字段为true,因为ssh mux循环从对等方接收到了一个关闭数据包,并通过发送一个关闭数据包进行处理,然后调用ch.close,设置sentClose。应用程序只在OpenChannel的结果上调用了一次Close。]