- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
TL;DR - 关闭 golang.org/x/crypto/ssh
session 以释放所有资源的正确方法是什么?
到目前为止我的调查:
golang.org/x/crypto/ssh
*Session
有一个 Close()
函数调用 *Channel
Close()
函数发送消息(我猜是远程服务器)关闭,但我没有看到任何关于关闭其他资源的信息,比如从 *Session
StdoutPipe()
函数。
查看 *Session
Wait()
代码,我看到 *Session stdinPipeWriter
已关闭,但与 无关标准输出管道
。
这个包感觉很像 os/exec
包,它保证使用 os/exec Wait()
函数将清理所有资源。在那里做一些简单的挖掘显示了 Wait()
函数中的一些相似之处。两者都使用以下结构来报告对它们的标准输出、标准错误、标准输入读取器/写入器的 io.Copy
调用的错误(好吧,如果我没看错的话,实际上只有一个错误)——显示的加密包:
var copyError error
for _ = range s.copyFuncs {
if err := <-s.errors; err != nil && copyError == nil {
copyError = err
}
}
但是 os/exec
Wait()
也调用了这个关闭描述符方法
c.closeDescriptors(c.closeAfterWait)
这只是在 io.Closer
接口(interface)的一部分上调用 close 方法:
func (c *Cmd) closeDescriptors(closers []io.Closer) {
for _, fd := range closers {
fd.Close()
}
}
当 os/exec
创建管道时,它会跟踪需要关闭的内容:
func (c *Cmd) StdoutPipe() (io.ReadCloser, error) {
if c.Stdout != nil {
return nil, errors.New("exec: Stdout already set")
}
if c.Process != nil {
return nil, errors.New("exec: StdoutPipe after process started")
}
pr, pw, err := os.Pipe()
if err != nil {
return nil, err
}
c.Stdout = pw
c.closeAfterStart = append(c.closeAfterStart, pw)
c.closeAfterWait = append(c.closeAfterWait, pr)
return pr, nil
}
在此期间,我注意到 x/cyrpto/ssh
*Session StdoutPipe()
返回一个 io.Reader
和 ox/exec
返回一个 io.ReadCloser
。并且 x/crypto/ssh
不会跟踪要关闭的内容。我在库中找不到对 os.Pipe()
的调用,所以可能实现不同,我遗漏了一些东西并且被 Pipe 名称弄糊涂了。
最佳答案
通过调用 Close()
关闭 session 。没有涉及文件描述符,也没有对 os.Pipe
的任何调用,因为从 Session.StdOutPipe
返回的“管道”在概念上只是一个管道,并且是类型ssh.Channel
。 Go channel 不需要关闭,因为关闭 channel 不是清理操作,而只是发送到 channel 的一种消息。 ssh 传输中只涉及一个网络连接。
您需要关闭的唯一资源是网络连接;没有其他系统资源可以释放。在 ssh.Client
上调用 Close()
将调用 ssh.Conn.Close
,然后关闭 net.Conn
.
如果您需要处理网络连接,您总是可以跳过ssh.Dial
便捷功能并自己拨号网络连接:
c, err := net.DialTimeout(network, addr, timeout)
if err != nil {
return nil, err
}
conn, chans, reqs, err := ssh.NewClientConn(c, addr, config)
if err != nil {
return nil, err
}
// calling conn.Close will close the underlying net.Conn
client := ssh.NewClient(c, chans, reqs)
关于go - 关闭加密 ssh session 以释放 golang 中所有资源的正确方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42590308/
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题? Update the question所以它是on-topic对于堆栈溢出。 10年前关闭。 Improve this qu
我错误地设置了 ssh key 的密码。 但是每次使用 key 时都要输入密码很烦人。 我想删除我的 key 的密码: $ ssh-keygen -p -f 但是,我担心 key 会被更改。 由于我
你好!我在连接到远程主机时遇到问题。我忘记了 ssh 密码,但我有 SSH key 的指纹。是否可以仅使用指纹进行连接? 最佳答案 不会。机器的指纹仅用于验证您正在连接您认为正在连接的机器。它是用于避
我有一个 Ubuntu 服务器 example.com 并且我已经通过 ssh 进入了它。但只有在我通过 ssh 进入它之后,我才意识到我打算执行 ssh -L 8000:localhost:9000
通过终端,我可以多次 SSH 连接到服务器: (客户端--->网关--->服务器1---->服务器2---) 但是现在要通过Java的JSch库来实现,怎么办呢?首先尝试了端口转发,但在终端上我没有这
在创建一个新的仓库(本地 + 远程)之后,我正在尝试推送提交。但是我遇到了 SSH key 的问题 在我的 ~/.ssh/config 中,我有一个 gitlab 条目定义为 Host MyRepoJ
我发现 ssh 和 ssh-keygen 有一种奇怪的行为:它们根本没有反应。 Cygwin 以管理员权限启动并正常运行。主机 192.168.1.1 已启动,我可以远程桌面到它: 当我尝试时: $
为什么eval语句返回 Illegal variable name $ eval "$(ssh-agent -s)" Illegal variable name. 最佳答案 请尝试$ eval "ss
我正在尝试通过以下命令从我的本地主机连接到远程主机。但是远程主机中有一个设置,我们登录后不久它会提示输入徽章 ID、密码和登录原因,因为它在 profile 中是这样编码的文件在 remote-hos
有时,我被迫在不稳定的互联网连接上使用 ssh。 ping some.doma.in PING some.doma.in (x.x.x.x): 56 data bytes Request timeou
This thread is a response to the titled question : Why ssh-agent doesn't forward my SSH certificate
关闭。这个问题是off-topic .它目前不接受答案。 想改善这个问题吗? Update the question所以它是 on-topic对于堆栈溢出。 8年前关闭。 Improve this q
因此,我在10.10.10.x子网中有一堆机器,基本上所有这些机器都以相同的方式配置。我将这些与我的10.10.11.x子网中的计算机区分开,后者具有不同的用途。 我希望能够输入“ssh 10.x”以
我不想在 vagrant box 上创建新的 SSH key 对,而是想重新使用主机上的 key 对,使用 agent forwarding 。我尝试过设置 config.ssh.forward_ag
我有一台服务器,可以通过ssh通过pubkey身份验证通过ssh访问: ssh "Host" -l "my identity" 这很好。但是,我无法在一个命令中使用我的私钥进行端口重定向和标识(这是我
创建一对 key 并通过 ssh-copy-id 将公钥发送到服务器后,我仍然无法在没有密码的情况下登录 ssh -v user@host 的输出 debug1:在/home/pumba/.ssh/k
我被困在 Permission denied (publickey) hell 中,试图将公钥复制到远程服务器,以便 Jenkins 可以在构建期间同步文件。 运行: sudo ssh-copy-id
我正在尝试通过我大学的代理服务器ssh到我们实验室的服务器之一。我们的目标是使用paramiko使其自动化,但我试图首先了解终端机级别中正在发生的事情。 我试过了 ssh -o ProxyComman
我在说明问题上有问题,我想通过SSH切换到我的Cisco交换机,但是我遇到了一些麻烦 我写了两个脚本, 有了这个我没有任何问题,我可以通过运行脚本并输入用户名和密码来更改默认网关: from Exsc
每个人 我目前正在使用一个集群,并且会经常使用“ssh”连接到它。有时我需要打开多个终端。因此,每次需要连接时,我都必须输入“ssh username@cluster.com”,然后输入“密码”(我在
我是一名优秀的程序员,十分优秀!