Запуск SCP через go exec.cmd - PullRequest
0 голосов
/ 30 июня 2018

Я пытаюсь запустить команду scp as через golang exec.cmd, потому что неофициальные реализации, доступные для передачи scp, не работают для меня. Scp выполняется до тех пор, пока не запрашивает пароль, а затем я не могу записать данные на стандартный ввод. Возможно ли, что stdin перенаправлен куда-то еще?

var cmd *exec.Cmd
if m.IsDir() {
    cmd = exec.Command("scp", "-r", src, user+"@"+client.Host+":"+dest)
} else {
    cmd = exec.Command("scp", src, user+"@"+client.Host+":"+dest)
}

cmdWriter, err := cmd.StdinPipe()
if err != nil {
    return err
}

err = cmd.Start()

if cred.Typ() == "PW" {
    cmdWriter.Write( []byte(cred.Data()+"\n") )
} else {
    log.Println( "credential typ not supported" )
}

err = cmd.Wait()
log.Println( "done" )
return err

Настройка cmd.Stdin на os.Stdin работает, но, конечно, мне нужно вручную вводить пароль, который не тот, который я хочу. Или вы бы вообще не рекомендовали этот способ запуска scp? Я могу запускать простые команды SSH на сервере (с помощью «golang.org/x/crypto/ssh»). Есть ли способ передать двоичные файлы только через сеанс SSH? Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 01 июля 2018

Я предполагаю, что вы работаете в Linux. Если вы хотите передать пароль на scp из командной строки, лучше всего использовать sshpass. Он должен быть доступен для установки из стандартных репозиториев пакетов в основных дистрибутивах Linux, просто установите его с apt или yum. Синтаксис sshpass -p [password] scp ...

Здесь я создаю bash сеанс и конвейерные команды к нему из StdinPipe:

func main() { 
    cmd := exec.Command("bash")
    cmdWriter, _ := cmd.StdinPipe()
    cmd.Start()

    cmdString := fmt.Sprintf("sshpass -p %s scp -r %s %s@%s:%s", password, src, user, client, dest)

    cmdWriter.Write([]byte(cmdString + "\n"))
    cmdWriter.Write([]byte("exit"    + "\n"))

    cmd.Wait()
}

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


Однако пакет "github.com/pkg/sftp" гораздо проще использовать для таких передач файлов. Вы можете найти простой пример того, как его использовать здесь . Обратите внимание, что использование nil для HostKeyCallback в конфигурации клиента не рекомендуется - используйте HostKeyCallback: ssh.InsecureIgnoreHostKey(), если вам абсолютно необходимо принять все ключи хоста.

0 голосов
/ 30 июня 2018

scp и ssh настаивают на чтении пароля из tty (или psuedo tty)

стандартный вывод из удаленного сеанса - это не так, поэтому он не будет работать

Стандартный пакет go golang.org / x / crypto / ssh поддерживает отправку паролей, поэтому, вероятно, есть обходной путь. scp реализован как сервер, который вызывается с помощью ssh , поэтому, вероятно, расширение существующей поддержки go ssh не составит труда

Однако всегда существует обходной путь для внешней программы! Как обсуждено здесь , это включает использование sshpass программы

...