Python:rsync 排除在脚本中无效,但在 bash 中有效

3 投票
1 回答
1411 浏览
提问于 2025-04-16 22:21

下面是我用来测试一个问题的脚本。

通过subprocess.check_call运行rsync命令时,无法正确排除从排除变量中获取的文件。

我在Python中打印命令的结果,编辑后再直接在bash终端中运行,以此进行比较,但在使用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)

这是Python脚本的输出和直接运行rsync命令的结果。

> 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/

注意:就在我准备发布这个内容时,我发现问题似乎出在'--exclude="file"'中的双引号上,去掉它们后就能正常工作。我尝试用'--exclude=\"file\"'来转义双引号,但这也不行。我需要双引号是因为文件名或目录名中可能会有空格。

我漏掉了什么呢?

1 个回答

4

是的,问题出在双引号上,不要对它们进行转义,直接去掉就行。

在命令行中,双引号是为了防止命令行对内容进行扩展。

而且,如果你像你展示的那样对它们进行转义,它们只是在Python层面上被转义,这样做没有意义,因为在单引号里面,双引号会自动被转义。

In [2]: '\"foo\"'
Out[2]: u'"foo"'

应该是这样的

In [3]: '\\"foo\\"'
Out[3]: u'\\"foo\\"'

撰写回答