0

I'm trying to add a public key under my local $HOME/.ssh/ directory using Go.

I've been running multiple commands with this the same code without problem, but not for this particular one.

identity := fmt.Sprintf("cat %s/.ssh/%s.pub", fileUtil.FindUserHomeDir(), p.sshkey.name)
address := fmt.Sprintf("| ssh %s@%s 'cat >> ~/.ssh/authorized_keys', p.projectname.name, p.host.name)

cmd := exec.Command(identity, address)

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

Basically I'm trying to run:

cat /home/foo/.ssh/foobar.pub | ssh foo@bar.com 'cat >> ~/.shh/authorized_keys'"

Which works fine if I run it through the command line directly.

I want to run this program in different OS X machines, where some don't have ssh-copy-id installed. So, I'm not considering to use it.

But anyway, I'm open to other suggestions. Thank you in advance.

Alessandro Resta
  • 1,102
  • 1
  • 19
  • 26
  • 1
    `exec.Command` isn't a shell, so there is no concept of `|`. See http://stackoverflow.com/questions/10781516/how-to-pipe-several-commands-in-go – JimB Oct 08 '15 at 15:18
  • You can use exec.Command to execute shell though: `sh -c command` – kostya Oct 08 '15 at 15:49

2 Answers2

4

You don't need to execute /bin/sh -c "cat file" to read a file in Go. Open the file normally, and give that to the ssh command

keyFile, err := os.Open(filename)
if err != nil {
    log.Fatal(err)
}

cmd := exec.Command("ssh", "user@host", "cat >> ~/.ssh/authorized_keys")
cmd.Stdin = keyFile

// run the command however you want
out, err := cmd.CombinedOutput()
if err != nil {
    fmt.Println(string(out))
    log.Fatal(err)
}
JimB
  • 104,193
  • 13
  • 262
  • 255
  • 1
    but when i want to copy-ssh-id, I didn't have the key installed in remote server. How to input my password? ```"ssh", "user@host"``` where to input the password? – chuixue Apr 13 '21 at 03:08
1

You could simply execute rsync or scp for this purpose.

Satyen Rai
  • 1,493
  • 1
  • 12
  • 19