2010-03-09 13 views
0

J'ai une application de sauvegarde en python qui doit fonctionner sous Windows. Il a besoin de la compatibilité UTF (pour pouvoir sauvegarder les répertoires contenant des caractères UTF comme les accents italiens). Le problème est qu'il utilise des programmes externes (plink, cygwin, ssh et rsync) et je n'arrive pas à les faire fonctionner. Le prototype est de 32 lignes, s'il vous plaît jeter un oeil:Implémentation python unicode (en utilisant des programmes externes: cygnative plink ssh rsync)

# -*- 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/κόσμε" [email protected]:/volatile/backup/vaidab/2010-03-03.15_41_56/ --link-dest=../2010-03-03.15_00_57'.encode('utf-8') 
execute(command) 

ne fonctionne toujours pas avec la version de nosklo, vérifier le résultat:

python prototype_unicode_new.py '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" /cygdr ive/c/\xce\xba\xcf\x8c\xcf\x83\xce\xbc\xce\xb5 [email protected]:/volatile/bac kup/vaidab/2010-03-03.15_41_56/'

OUT: « \ nNombre des fichiers: 0 \ nNombre des fichiers transférés: 0 \ nTaille totale du fichier: 0 b ytes \ nTotal taille du fichier transféré: 0 octet \ nDonnées littérales: 0 octet \ nCalendrier: 0 octet \ nTaille de la liste de fichiers: 9 \ nGénération de la liste de fichiers: 0.001 secondes \ nFichier Temps de transfert: 0,000 secondes \ nTotale des octets envoyés: 22 \ nTotal octets reçus: 12 \ n \ nsent 22 octets reçus 12 octets 68.00 octets/s \ ntotal la taille est 0 accélération est 0.00 \ n ' ERRS:' rsync: lien_stat "/ cygdrive/c/\ xc3 \ x8e \ xc2 \ xba \ xc3 \ x8f \ xc5 \ x92 \ Échec: Aucun fichier ou répertoire (2) \ nrs Erreur ync: certains fichiers/attr n'ont pas été transférés (xc3 \ x8f \ xc 6 \ x92 \ xc3 \ x8e \ xc2 \ xbc \ xc3 \ x8e \ xc2 \ xb5 voir les erreurs précédentes) (code 23) at /home/lapo/packaging/rsync-3.0.6-1/src/rsync-3.0.6/main.c(1039) [expéditeur = 3.0. 6] \ n » RET: 23

+0

Veuillez inclure le code dans votre question (il y a un balisage spécial pour cela). Vous ne pouvez pas attendre de nous pour télécharger un fichier zip ... – ChristopheD

+0

32 lignes est trop petit. Veuillez copier la source et collez-la sur la question. Je – nosklo

+0

inclus dans le fichier zip les fichiers binaires (rsync, cygnative, Plink et ssh + dll pour que vous puissiez utiliser tous les outils) – vaidab

Répondre

1
  • Ne pas utiliser shell=True. JAMAIS. Il invoque inutilement un shell pour appeler votre programme.
  • Transmettez les paramètres sous la forme d'une liste au lieu d'une chaîne.

Cet exemple devrait fonctionner, à condition que les paramètres sont à droite et le rsync.exe est dans le dossier en cours (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'), 
      '[email protected]:/volatile/backup/vaidab/2010-03-03.15_41_56/', 
      '--link-dest=../2010-03-03.15_00_57'] 

execute(command) 
+0

ne fonctionne pas, même problème (vérifier ci-dessus) – vaidab

+1

Eh bien, il semble que votre système de fichiers n'UTF- 8. Que retourne 'sys.getfilesystemencoding()'? Peut-être essayer d'utiliser cela comme encodage? – nosklo

+0

il renvoie mbcs. Je modifié à .encode ('') et MBCS: > python prototype_unicode_new.py « rsync.exe --stats -az --numeric-ids --delete --blocking-io---modify fenêtre = 2 - no-groupe --chmod = u = rwx, g =, o = -e "cygnative plink -ssh -2 -batch -pw test"/cygdr ive/c/?? s \ xb5e [email protected]: /volatile/backup/vaidab/2010-03-03.15_41_56/ ' ... ERRS:' rsync: lien_stat "/ cygdrive/c/?? s \ xc2 \ xb5e" a échoué: aucun fichier ou direc tory – vaidab

0

Un morceau de code qui surpasse toute intelligence:

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) 

Quel est le point de doctests si vous ne les exécutez pas?

+0

vrai, c'était un reste, désolé pour cela. – vaidab