Python: rsync exclusions not working in script, works in bash shell
Below is a script I am using to test a problem.
Running an rsync command via subprocess.check_call does not work in excluding files obtained from an exclude variable.
I am printing the result of the command from Python, editing it and then running it in a bash shell 开发者_如何学Pythondirectly as a comparison and it fails to exclude my exclusions when using Python.
#!/usr/bin/env python3.1
import subprocess
exclude = 'exclude_me_dir, exclude_me_file.txt'
source_path = '/tmp/source'
path_to_backup_file_name = '/tmp/destination'
engine_options = '-axh --delete --delete-excluded'
def rsync_backup(source_path, path_to_backup_file_name, exclude, engine_options):
exclusions = ['--exclude="%s"' % x.strip() for x in exclude.split(',')]
rsync_command = ['rsync'] + exclusions + engine_options.split() + [source_path + '/', path_to_backup_file_name]
print(rsync_command)
return subprocess.check_call(rsync_command)
rsync_backup(source_path, path_to_backup_file_name, exclude, engine_options)
This is the output of the Python script and running the rsync command directly.
> pwd
/root
> ls /tmp/source/
exclude_me_dir/ exclude_me_file.txt file1.txt folder1/
> /tmp/rsynctest.py
['rsync', '--exclude="exclude_me_dir"', '--exclude="exclude_me_file.txt"', '-axh', '--delete', '--delete-excluded', '/tmp/source/', '/tmp/destination']
> ls /tmp/destination/
exclude_me_dir/ exclude_me_file.txt file1.txt folder1/
> rsync --exclude="exclude_me_dir" --exclude="exclude_me_file.txt" -axh --delete --delete-excluded /tmp/source/ /tmp/destination
> ls /tmp/destination/
file1.txt folder1/
N.B. As I was about to post this I discovered the problem appears to be the double quotes in '--exclude="file"' as if I remove them it works. I tried escaping them like so '--exclude=\"file\"'. but this does not work either. I require the double quotes for occasions when a space occurs in a file name or directory.
What am I missing?
Yes the double quotes are the problem, don't escape them, just drop them.
They are just required on the shell to hinder the shell from expanding.
Moreover: If you escape them the way you've shown, they are only escaped on the python level where it makes no sense, because double quotes are automatically escaped inside of single quotes
In [2]: '\"foo\"'
Out[2]: u'"foo"'
it should be
In [3]: '\\"foo\\"'
Out[3]: u'\\"foo\\"'
精彩评论