# #go #ssh #output #buffer
Вопрос:
Я использую пакет ssh для подключения к серверу 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 := amp;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 = amp;b // 👈 this is the place I am concerned with
// Finally, run the command
err = session.Run(command)
return b.String(), err
}
Эта команда обычно работает нормально: она всегда подключается, но случайным образом не возвращает результат.
Прежде чем продолжить свои исследования, я хотел убедиться, что выходной буфер очищен, прежде чем возвращать вывод. Так ли это на самом деле?
Комментарии:
1. Если ОС Linux, то гарантированно будет сброшен только stderr, а не stdout AFAIK.
2. Попробуйте также проверить stderr на наличие каких-либо выходных данных там. Ожидается, что любые проблемы с вводом-выводом будут возвращены как ошибка
Session.Run
.
Ответ №1:
В этом примере использования/проблеме вы можете видеть, что stdout и stderr связаны с одним и тем же буфером.
посмотрите, поможет ли это в вашем случае.
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 = amp;b
sess.Stderr = amp;b
err = sess.Shell()
if err != nil {
log.Fatal(err)
}
...
_, err = fmt.Fprintf(stdin, "%sn", cmd)