0

I need in python execute this command and enter password from keyboard, this is works:

import os
cmd = "cat /home/user1/.ssh/id_rsa.pub | ssh user2@host.net \'cat >> .ssh/authorized_keys\' > /dev/null 2>&1"
os.system(cmd)

As you can see I want append public key to remote host via ssh.
See here: equivalent-of-ftp-put-and-append-in-scp and here: copy-and-append-files-to-a-remote-machine-cat-error

Of course I want it do it without user input I've try pexpect and I think command is to weird for it:

import pexpect

child = pexpect.spawn(command=cmd, timeout=10, logfile=open('debug.txt', 'a+'))
matched = child.expect(['Password:', pexpect.EOF, pexpect.TIMEOUT])
if matched == 0:
    child.sendline(passwd)

in debug.txt:

ssh-rsa AAAA..........vcxv233x5v3543sfsfvsv user1@host1
/bin/cat: |: No such file or directory
/bin/cat: ssh: No such file or directory
/bin/cat: user2@host.net: No such file or directory
/bin/cat: cat >> .ssh/authorized_keys: No such file or directory
/bin/cat: >: No such file or directory
/bin/cat: 2>&1: No such file or directory

I see two solution:

  1. fix command for pexpect, that it recognize whole string as one command or,
  2. inject/write passwd to stdin as fake user, but how!?!?
Community
  • 1
  • 1
emcek
  • 459
  • 1
  • 6
  • 17
  • unrelated: there is no need to escape single quotes inside double quotes in Python: `"_'|'_"` – jfs Oct 24 '15 at 14:48
  • have you considered `ssh-copy-id` instead? – jfs Oct 24 '15 at 14:52
  • @J.F.Sebastian Nope, isn't available. – emcek Oct 26 '15 at 08:36
  • [`ssh-copy-id` is just a shell script](https://github.com/openssh/openssh-portable/blob/master/contrib/ssh-copy-id). If you have openssh client installed (`ssh` command) then it should be available. – jfs Oct 26 '15 at 10:46

2 Answers2

1

From the pexpect docs:

Remember that Pexpect does NOT interpret shell meta characters such as redirect, pipe, or wild cards (>, |, or *). This is a common mistake. If you want to run a command and pipe it through another command then you must also start a shell. For example::

child = pexpect.spawn('/bin/bash -c "ls -l | grep LOG > logs.txt"')
child.expect(pexpect.EOF)
jfs
  • 399,953
  • 195
  • 994
  • 1,670
0

That worked for me:

command = "/bin/bash -c \"cat /home/user1/.ssh/id_rsa.pub | ssh user2@host.net \'cat >> ~/.ssh/authorized_keys\' > /dev/null 2>&1\""
child = spawn(command=command, timeout=5)
emcek
  • 459
  • 1
  • 6
  • 17