简体   繁体   English

python unicode实现(使用外部程序:cygnative plink ssh rsync)

[英]python unicode implementation (using external programs: cygnative plink ssh rsync)

I have a backup applications in python that needs to work on Windows. 我在python中有一个备份应用程序,需要在Windows上运行。 It needs UTF compatibility (to be able to backup directories that contain UTF characters like italian accents). 它需要UTF兼容性(才能备份包含UTF字符(如意大利口音)的目录)。 The problem is it uses external programs (plink, cygwin, ssh and rsync) and I can't get them working. 问题是它使用外部程序(plink,cygwin,ssh和rsync),但我无法使它们正常工作。 The prototype is 32 lines long, please take a look: 原型长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)

Still doesn't work with nosklo's version, check the result: 仍然不适用于nosklo的版本,请检查结果:

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 vaidab@192.168.1.86:/volatile/bac kup/vaidab/2010-03-03.15_41_56/' 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测试” / cygdr ive / c / \\ xce \\ xba \\ xcf \\ x8c \\ xcf \\ x83 \\ xce \\ xbc \\ xce \\ xb5 vaidab@192.168.1.86:/ volatile / bac kup / vaidab / 2010-03-03.15_41_56 /'

OUT: '\\nNumber of files: 0\\nNumber of files transferred: 0\\nTotal file size: 0 b ytes\\nTotal transferred file size: 0 bytes\\nLiteral data: 0 bytes\\nMatched data: 0 bytes\\nFile list size: 9\\nFile list generation time: 0.001 seconds\\nFile list transfer time: 0.000 seconds\\nTotal bytes sent: 22\\nTotal bytes received: 12\\n\\ nsent 22 bytes received 12 bytes 68.00 bytes/sec\\ntotal size is 0 speedup is 0.00\\n' 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" failed: No such file or directory (2)\\nrs ync error: some files/attrs were not transferred (see previous errors) (code 23) at /home/lapo/packaging/rsync-3.0.6-1/src/rsync-3.0.6/main.c(1039) [sender=3.0. 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 \\ nsent接收的22个字节12字节68.00字节/秒\\ n总大小为0,加速率为0.00 \\\\ n'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错误:在/home/lapo/packaging/rsync-3.0.6处未传输某些文件/属性(请参阅先前的错误)(代码23) -1 / src / rsync-3.0.6 / main.c(1039)[发送者= 3.0。 6]\\n' RET: 23 6] \\ n'RET:23

  • Don't use shell=True . 不要使用shell=True EVER . 永远 It needlessy invokes a shell to call your program. 它不需要调用外壳程序来调用您的程序。
  • Pass the parameters as a list instead of a string. 将参数作为列表而不是字符串传递。

This example should work, provided the parameters are right and the rsync.exe is in current folder (or PATH ): 只要参数正确并且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)

A piece of code that passeth all understanding: 一段经过所有理解的代码:

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)

What's the point of doctests if you don't run them? 如果不运行doctest,有什么意义?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM