Отправка файла через SSH на ходу - PullRequest
0 голосов
/ 12 ноября 2018

Я нашел этот ответ до публикации этого вопроса, но ответ мне не ясен.

Вот код ответа:

conn, err := ssh.Dial("tcp", hostname+":22", config)
if err != nil {
    return err
}

session, err := conn.NewSession()
if err != nil {
    return err
}
defer session.Close()

r, err := session.StdoutPipe()
if err != nil {
    return err
}

name := fmt.Sprintf("%s/backup_folder_%v.tar.gz", path, time.Now().Unix())
file, err := os.OpenFile(name, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644)
if err != nil {
    return err
}
defer file.Close()

if err := session.Start(cmd); err != nil {
    return err
}

n, err := io.Copy(file, r)
if err != nil {
    return err
}

if err := session.Wait(); err != nil {
    return err
}

return nil

Я не понимаю связи между переменной cmd и io.Copy, где и как она знает, какой файл копировать. Мне нравится идея использования io.Copy, но я не знаю, как создать файл с помощью ssh и начать отправку на него содержимого с помощью io.Copy.

1 Ответ

0 голосов
/ 12 ноября 2018

Вот минимальный пример использования Go в качестве scp клиента:

config := &ssh.ClientConfig{
    User: "user",
    Auth: []ssh.AuthMethod{
        ssh.Password("pass"),
    },
    HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}

client, _ := ssh.Dial("tcp", "remotehost:22", config)
defer client.Close()

session, _ := client.NewSession()
defer session.Close()

file, _ := os.Open("filetocopy")
defer file.Close()
stat, _ := file.Stat()

wg := sync.WaitGroup{}
wg.Add(1)

go func() {
    hostIn, _ := session.StdinPipe()
    defer hostIn.Close()
    fmt.Fprintf(hostIn, "C0664 %d %s\n", stat.Size(), "filecopyname")
    io.Copy(hostIn, file)
    fmt.Fprint(hostIn, "\x00")
    wg.Done()
}()

session.Run("/usr/bin/scp -t /remotedirectory/")
wg.Wait()

Обратите внимание, что я проигнорировал все ошибки только для краткости.

  1. session.StdinPipe() создаст канал для записи для удаленного хоста.
  2. fmt.Fprintf(... "C0664 ...") сообщит о начале файла с разрешением 0664, размером stat.Size() и удаленным именем файла filecopyname.
  3. io.Copy(hostIn, file) запишет содержимое file в hostIn.
  4. fmt.Fprint(hostIn, "\x00") будет сигнализировать конец файла.
  5. session.Run("/usr/bin/scp -qt /remotedirectory/") запустит команду scp.

Редактировать : добавлена ​​группа ожидания для запроса ОП

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...