Вызываемая программа не работает, если запустить через os.exec - PullRequest
0 голосов
/ 03 февраля 2019

Я не уверен, является ли это проблемой вызванной программы или проблема вызвана тем, как я вызываю программу.Из-за этого я начинаю с исходного кода.

Мне нужно вызвать ssh из программы (если вас интересуют причины, о которых я упомяну ниже), но ssh молча завершается.

КогдаЯ вызываю ssh -v user@remotehost из оболочки, это успешно:

  • выводится требуемый отладочный вывод на stderr
  • У меня спрашивают пароль
  • Я вижу удаленныйоболочка hosts

Но когда я делаю то же самое из моей программы (myssh -v user@remotehost, происходит только это:

  • Меня просят ввести пароль

Не отображаются выходные данные отладки на stderr и я не достигаю оболочки удаленных хостов.

Это мой исходный код:

package main

import (
        "fmt"
        "log"
        "os"
        "os/exec"
)

func main() {
        params := os.Args[1:]
        fmt.Printf("passing this to ssh: %s\n", params)
        cmd := exec.Command("ssh", params...)
        err := cmd.Run()
        if err != nil {
                log.Fatal(err)
        }
}

Причина, по которой я написал этот код:Я использую Ansible, который вызывает ssh. Мне нужно «манипулировать» параметрами, которые Ansible передает в ssh. До сих пор я спрашивал в списках рассылки OpenSSH и Ansible, в OpenSSH и Ansible нет никаких средств для изменения параметров (для других это, но не те, которые мне нужны). Лучшее предложение я идуЯ хочу реализовать альтернативную команду ssh для Ansible, использовать ее для получения и изменения параметров и передачи их в реальный ssh.

1 Ответ

0 голосов
/ 03 февраля 2019

Вы захватываете Stdout и Stderr с cmd?Здесь отправляются соответствующие выходные данные команды.Документация для exec.Command имеет действительно хороший пример этого.

В вашем случае вам также потребуется настроить Stdin, чтобы вы могли передать пароль, например.

Вот очень простой пример, основанный на вашем коде:

package main

import (
  "bytes"
  "fmt"
  "log"
  "os"
  "os/exec"
)

func main() {
  params := os.Args[1:]
  fmt.Println("Passing this to ssh: %s", params)

  var stdin  bytes.Buffer
  var stdout bytes.Buffer
  var stderr bytes.Bufer

  cmd := exec.Command("ssh", params...)
  cmd.Stdin  = &stdin
  cmd.Stdout = &stdout
  cmd.Stderr = &stderr

  if err := cmd.Run(); err != nil {
    log.Fatal(err)
  }

  fmt.Println("Stdout: %s", stdout.String())
  fmt.Println("stderr: %s", stderr.String())
}

Поскольку stdin, stdout и stderr - все bytes.Buffer s, вы можете читать и писатьиз них, как и любой другой буфер.

Вы также можете рассмотреть возможность использования пакета golang.org/x/crypto/ssh, который предоставляет собственный интерфейс SSH для Go, вместо использования подпроцессов.

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