Pergunta

Eu tenho um aplicativos de backup em python que precisa trabalhar no Windows. Ele precisa de compatibilidade UTF (para ser capaz de diretórios de backup que contêm caracteres UTF como acentos italiano). O problema é que ele usa programas externos (plink, cygwin, ssh e rsync) e eu não posso levá-los a trabalhar. O protótipo é de 32 linhas longas, por favor, dê uma olhada:

# -*- 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)

ainda não funciona com a versão de nosklo, verificar o resultado:

prototype_unicode_new.py python 'Rsync.exe --stats -az --numeric-ids --delete --blocking-io --modify-janela = 2 - não-grupo --chmod = u = RWX, g =, o = -e "cygnative Plink -ssh -2 -batch -pw teste" / cygdr ive / c / \ XCE \ Xba \ xcf \ x8c \ xcf \ x83 \ XCE \ XBC \ XCE \ XB5 vaidab@192.168.1.86: / volátil / bac kup / väidab / 2010-03-03.15_41_56 / '

OUT: '\ nNúmero de arquivos: 0 \ nNúmero de arquivos transferidos: tamanho do arquivo 0 \ nTotal: 0 b ytes \ nTotal transferido tamanho: 0 bytes \ data nLiteral: 0 bytes \ data nMatched: 0 bytes \ o tamanho da lista nArquivar: 9 \ nArquivar tempo lista geração: 0,001 segundos \ lista nArquivar tempo de transferência: 0,000 segundos \ nTotal bytes enviado: 22 \ nTotal bytes recebidos: 12 \ n \ nsent 22 bytes recebidos bytes 12 68.00 bytes / seg \ tamanho Ntotal é 0 aumento de velocidade é 0.00 \ n' Erra: '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" Falha: Nenhum tal lima ou diretório (2) \ nrs erro YNC: alguns arquivos / attrs não foram transferidos (ver erros anteriores) (código 23) em /home/lapo/packaging/rsync-3.0.6-1/src/rsync-3.0.6/main.c(1039) [remetente = 3,0. 6] \ n' RET: 23

Foi útil?

Solução

  • Não use shell=True. sempre . Ele needlessy invoca um shell para chamar seu programa.
  • Passe os parâmetros como uma lista em vez de uma string.

Este exemplo deve funcionar, desde que os parâmetros são direito eo rsync.exe está na pasta atual (ou 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)

Outras dicas

Um pedaço de código que excede todo o entendimento:

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)

O que é o ponto de doctests se você não executá-los?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top