Problem with args when trying to run rsync in Python 3 subprocess

741 views Asked by At

I am developing a backup python program, one of the modules makes a rsync backup of a remote folder into my local device.

This is the part of the code where I have the problem:

            try:
                process = subprocess.Popen(
                    ['sshpass',
                    '-p',
                    password,
                    'rsync',
                    '-avz',
                    '-e',
                    'ssh -o StrictHostKeyChecking=no',
                    '-p',
                    port,
                    '{}@{}:{}'.format(user, host, folder),
                    dest_folder],
                    stdout=subprocess.PIPE
                )
                output = process.communicate()[0]
                if int(process.returncode) != 0:
                    print('Command failed. Return code : {}'.format(process.returncode))
                    exit(1)
                return output
            except Exception as e:
                print(e)
                exit(1)

The shown error is:

Unexpected remote arg: [email protected]:/folder1/folder2/
rsync error: syntax or usage error (code 1) at main.c(1372) [sender=3.1.3]
Command failed. Return code : 1

I believe that the problem is with the array in Popen. If I run the single command in bash I rsync successfully.

What should I change from subprocess.Popen array?

1

There are 1 answers

2
Shumatsu On BEST ANSWER

This is caused by -p flag being consumed by rsync rather than ssh, and as such the destination effectively is set to port.

The -e argument of rsync takes exactly one parameter. That means that only 'ssh -o StrictHostKeyChecking=no' will be passed as an argument. Unluckily for you, -p is an actual flag of rsync, and as such it's processed without error. It means 'preserve permissions'. This means that rather than setting port to use with ssh, you're passing a flag to rsync, and the next parameter gets interpreted as a destination.

You can fix it by changing

 'ssh -o StrictHostKeyChecking=no',
 '-p',
 port,

to simply

 'ssh -o StrictHostKeyChecking=no -p {}'.format(port),