Реализация Python Unicode (с использованием внешних программ: Cygnative Plink SSH rsync) - PullRequest
0 голосов
/ 09 марта 2010

У меня есть приложения для резервного копирования в python, которые должны работать в Windows. Требуется совместимость с UTF (чтобы иметь возможность создавать резервные копии каталогов, содержащих символы UTF, такие как итальянские акценты). Проблема в том, что он использует внешние программы (plink, cygwin, ssh и rsync), и я не могу заставить их работать. Прототип длиной 32 строки, пожалуйста, посмотрите:

# -*- coding: utf-8 -*-
import subprocess

def safestr(obj, encoding='utf-8'):
    r"""Converts any given object to utf-8 encoded string.

        >>> safestr('hello')
        'hello'
        >>> safestr(u'\u1234')
        '\xe1\x88\xb4'
        >>> safestr(2)
        '2'
    """
    if isinstance(obj, unicode):
        return obj.encode("utf-8")
    elif isinstance(obj, str):
        return obj.encode
    else:
        return str(obj)

def execute(command):
    pipe = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
    out, errs = pipe.communicate()
    retcode = pipe.poll()

    print "OUT: " + repr(out)
    print "ERRS: " + repr(errs)
    print "RET: " + str(retcode)


command = u'rsync --stats -az --numeric-ids --delete --blocking-io --modify-window=2 --no-group --chmod=u=rwX,g=,o=  -e \'cygnative plink -ssh -2 -batch  -pw test \' "/cygdrive/c/κόσμε" vaidab@192.168.1.86:/volatile/backup/vaidab/2010-03-03.15_41_56/ --link-dest=../2010-03-03.15_00_57'.encode('utf-8')
execute(command)

По-прежнему не работает с версией nosklo, проверьте результат:

python prototype_unicode_new.py 'rsync.exe --stats -az --numeric-ids - удалить --blocking-io --modify-window = 2 - no-group --chmod = u = rwX, g =, o = -e "cygnative plink -ssh -2 -batch -pw test" / cygdr ive / c / \ xce \ xba \ xcf \ x8c \ xcf \ x83 \ xce \ xbc \ xce \ xb5 vaidab@192.168.1.86: / volatile / bac куп / vaidab / 2010-03-03.15_41_56 / '

OUT: '\ nКоличество файлов: 0 \ nКоличество переданных файлов: 0 \ nОбщий размер файла: 0 b ytes \ nОбщий размер переданного файла: 0 байт \ nЛитеральные данные: 0 байт \ nСообщенные данные: 0 байт \ n Размер списка файлов: 9 \ n Время создания списка файлов: 0,001 секунды \ n Список файлов время передачи: 0,000 секунд \ nВсего байт отправлено: 22 \ nВсего байт получено: 12 \ n \ отправлено 22 байта, получено 12 байтов, 68,00 байт / сек \ общий размер равен 0 0,00 \ п» ERRS: «rsync: link_stat» / cygdrive / c / \ xc3 \ x8e \ xc2 \ xba \ xc3 \ x8f \ xc5 \ x92 \ xc3 \ x8f \ xc 6 \ x92 \ xc3 \ x8e \ xc2 \ xbc \ xc3 \ x8e \ xc2 \ xb5 "не удалось: нет такого файла или каталога (2) \ nrs Ошибка YNC: некоторые файлы / атрибуты не были переданы (см. предыдущие ошибки) (код 23) по адресу /home/lapo/packaging/rsync-3.0.6-1/src/rsync-3.0.6/main.c(1039) [sender = 3.0. 6] \ п» RET: 23

Ответы [ 2 ]

1 голос
/ 09 марта 2010
  • Не используйте shell=True. НАВСЕГДА . Это излишне вызывает оболочку для вызова вашей программы.
  • Передача параметров в виде списка вместо строки.

Этот пример должен работать, при условии, что параметры верны и rsync.exe находится в текущей папке (или PATH):

# -*- coding: utf-8 -*-
import subprocess

def execute(command):
    pipe = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    out, errs = pipe.communicate()
    retcode = pipe.poll()

    print "OUT: " + repr(out)
    print "ERRS: " + repr(errs)
    print "RET: " + str(retcode)
    return out


command = ['rsync.exe', '--stats', '-az', '--numeric-ids', '--delete', 
           '--blocking-io', '--modify-window=2', '--no-group', 
           '--chmod=u=rwX,g=,o=', '-e', 
           'cygnative plink -ssh -2 -batch -pw test', 
           u'/cygdrive/c/κόσμε'.encode('utf-8'), 
           'vaidab@192.168.1.86:/volatile/backup/vaidab/2010-03-03.15_41_56/', 
           '--link-dest=../2010-03-03.15_00_57']

execute(command)
0 голосов
/ 09 марта 2010

Кусок кода, который превосходит все понимание:

if isinstance(obj, unicode):
    return obj.encode("utf-8")
elif isinstance(obj, str):
    return obj.encode
    # the above is returning a METHOD ***************************
else:
    return str(obj)

Какой смысл докатестов, если вы их не запускаете?

...