Python: исключения rsync не работают в скрипте, работают в оболочке bash - PullRequest
3 голосов
/ 27 июля 2011

Ниже приведен скрипт, который я использую для проверки проблемы.

Выполнение команды rsync через subprocess.check_call не работает при исключении файлов, полученных из переменной exclude.

Я печатаю результат команды из 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/

N.B. Когда я собирался опубликовать это, я обнаружил, что проблема заключается в двойных кавычках в '--exclude = "file" ", как будто я удаляю их, это работает. Я пытался их экранировать примерно так: --exclude = \ "file \" '. но это тоже не работает. Мне требуются двойные кавычки для случаев, когда в имени файла или директории появляется пробел.

Чего мне не хватает?

1 Ответ

4 голосов
/ 27 июля 2011

Да, двойные кавычки - это проблема, не избегайте их, просто отбросьте их.

Они просто необходимы на оболочке, чтобы препятствовать расширению оболочки.

Более того: Есливы избегаете их, как вы показали, они выходят только на уровне питона, где это не имеет смысла, потому что двойные кавычки автоматически экранируются внутри одинарных кавычек

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

это должно быть

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