5

I'm trying to execute a rsync command via subrocess & popen. Everything's ok until I don't put the rsh subcommand where things go wrong.

from subprocess import Popen
args = ['-avz', '--rsh="ssh -C -p 22 -i /home/bond/.ssh/test"', 'bond@localhost:/home/bond/Bureau', '/home/bond/data/user/bond/backups/']

p = Popen(['rsync'] + args, shell=False)
print p.wait()

#just printing generated command:
print ' '.join(['rsync']+args)

I've tried to escape the '--rsh="ssh -C -p 22 -i /home/bond/.ssh/test"' in many ways, but it seems that it's not the problem.

I'm getting the error rsync: Failed to exec ssh -C -p 22 -i /home/bond/.ssh/test: No such file or directory (2)

If I copy/paste the same args that I output at the time, I'm getting a correct execution of the command.

Thanks.

oho
  • 188
  • 8
  • Just a hint, not related to your problem: If you add some lines to your `~/.ssh/config`, namely `Host mybackup`, `Hostname localhost`, `User bond`, `Port 22` (which is redundant), `Compression yes` and `IdentityFile /home/bond/.ssh/test`, you can use `['rsync', '-avz', 'mybackup:/home/bond/Bureau', ''/home/bond/data/user/bond/backups/']`. – glglgl Sep 19 '12 at 13:31
  • @mgilson Yours should rather be an answer... – glglgl Sep 19 '12 at 13:32
  • @glglgl thanks for this hint. In my case I have to deal with many users/ports, that's why I prefere to use the rsh option instead. – oho Sep 19 '12 at 13:34
  • @glglgl -- changed it to an answer. – mgilson Sep 19 '12 at 13:47
  • @azerty Ah so. In this case, a dedicated interface for setting these might make sense. – glglgl Sep 19 '12 at 14:07

2 Answers2

5

What happens if you use '--rsh=ssh -C -p 22 -i /home/bond/.ssh/test' instead (I removed the double quotes).

I suspect that this should work. What happens when you cut/paste your line into the commandline is that your shell sees the double quotes and removes them but uses them to prevent -C -p etc. from being interpreted as separate arguments. when you call subprocess.Popen with a list, you've already partitioned the arguments without the help of the shell, so you no longer need the quotes to preserve where the arguments should be split.

mgilson
  • 300,191
  • 65
  • 633
  • 696
  • To expand on this, he means that don't quote the 'ssh -p 22 -i ..." part. As an example, this was the list i was passing into check_call/Popen: ["rsync", "--rsh='{}'".format(someVariable), "file" "mark@something.com:/var/www"] and it didn't work. To make it work, i removed the quotes around the {} where i was inserting the --rsh arguments. So this works: ["rsync", "--rsh={}".format(someVariable), "file" "mark@something.com:/var/www"] – mgrandi Aug 12 '14 at 23:22
0

Having the same problem, I googled this issue extensively. It would seem you simply cannot pass arguments to ssh with subprocess. Ultimately, I wrote a shell script to run the rsync command, which I could pass arguments to via subprocess.call(['rsyncscript', src, dest, sshkey]). The shell script was: /usr/bin/rsync -az -e "ssh -i $3" $1 $2

This fixed the problem.

Andy
  • 1