【问题标题】:Is the output from ssh guaranteed to be retrieved?是否保证可以检索 ssh 的输出?
【发布时间】:2021-08-17 08:46:51
【问题描述】:

我使用ssh package 连接到Linux 服务器并检索命令的输出。我为此编写的辅助函数如下:

func sshRunCommand(host string, command string) (output string, err error) {
    keyData, err := ioutil.ReadFile("srv.private.openssh")
    if err != nil {
        return "", err
    }
    key, err := ssh.ParsePrivateKey(keyData)
    if err != nil {
        return "", err
    }
    // Authentication
    config := &ssh.ClientConfig{
        User: "root",
        HostKeyCallback: ssh.InsecureIgnoreHostKey(),
        Auth: []ssh.AuthMethod{
            ssh.PublicKeys(key),
        },
    }
    // Connect
    client, err := ssh.Dial("tcp", net.JoinHostPort(host, "22"), config)
    if err != nil {
        return "", err
    }
    // Create a session. It is one session per command.
    session, err := client.NewSession()
    if err != nil {
        return "", err
    }
    defer session.Close()
    var b bytes.Buffer
    session.Stdout = &b // ???? this is the place I am concerned with
    // Finally, run the command
    err = session.Run(command)
    return b.String(), err
}

此命令通常工作正常:它始终连接但随机不返回输出。

在进一步调查之前,我想确保在返回输出之前刷新输出缓冲区。是这样吗?

【问题讨论】:

  • 如果操作系统是 Linux,只有 stderr 保证被刷新,而不是 stdout AFAIK。
  • 尝试检查 stderr 是否有任何输出。任何 io 问题都应作为错误从 Session.Run 返回。

标签: go ssh output buffer


【解决方案1】:

在这个用例/问题中,您可以看到标准输出标准错误链接到同一个缓冲区。
看看这对你的情况是否有帮助。


    sess, err := client.NewSession()
    if err != nil {
        log.Fatal("Failed to create session: ", err)
    }
    defer sess.Close()

    stdin, err := sess.StdinPipe()
    if err != nil {
        log.Fatal(err)
    }

    var b bytes.Buffer
    sess.Stdout = &b
    sess.Stderr = &b

    err = sess.Shell()
    if err != nil {
        log.Fatal(err)
    }

    ...

    _, err = fmt.Fprintf(stdin, "%s\n", cmd)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-30
    • 2012-05-30
    • 1970-01-01
    • 1970-01-01
    • 2018-07-13
    • 2014-01-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多