开发者

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\\"'
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜