好的,有点背影。我正在为我的应用编写备份和恢复功能。我想允许其备份文件的加密密码允许任何unicode字符。然后我被限制使用子进程来实际运行备份命令,这可以正常使用:
cmd = ['sudo', CMD_SCRIPT, 'python', script, 'backup', password, backup_to]
subprocess.check_call(cmd)
我已经能够使用相同的unicode密码解密文件,它似乎工作得很好
我的问题出现在恢复阶段;因为恢复过程取消了用于与客户交互的服务器,我需要在单独的守护程序中启动此过程。我完成此任务的代码如下:
cmd = ['python', script, 'restore', password, backup_file, 'user']
proc = subprocess.Popen(['at', 'now'], stdin=subprocess.PIPE)
proc.communicate(' '.join(cmd))
当subprocess.PIPE尝试写入这段代码时(不是我的,可以在subprocess.communicate中找到):
if self.stdin:
if input:
try:
self.stdin.write(input) # < HERE
except IOError as e:
if e.errno != errno.EPIPE and e.errno != errno.EINVAL:
raise
self.stdin.close()
它无法引发UnicodeEncodeError:
'ascii' codec can't encode character u'\xdc' in position 66: ordinal not in range(128)
我试过设置proc.stdin.encoding ='utf-8',但它告诉我这个属性是只读的,我在初始化时也试过设置env = {'PYTHONIOENCODING':'utf-8'}我的Popen实例。这些都没有奏效。
是否有我可以使用的另一个stdin对象允许我定义编码?请帮忙。
答案 0 :(得分:1)
好的......我现在将暂停子进程中的lynch mob。在python 2中混合使用unicode和str类型时,这完全是我的不小心。
将一个列表传递给check_call()命令时,似乎有一些功能可以在向os发出命令之前对所有unicode进行编码。当使用communic()时,它需要一个字符串,但是将列表中的unicode和str类型混合传递给str类型.join操作它依赖于pythons'有用'的组合操作,默认使用'ascii'进行编码和解码作为编解码器。 当我更改代码时,确保列表中的所有内容都是unicode,然后在传递它时对其进行编码,以便按预期方式进行通信。确保我的脚本,密码和backup_file变量为unicode类型后,我的代码现在看起来像:
cmd = [u'python', script, u'restore', password, backup_file, u'user']
proc = subprocess.Popen(['at', 'now'], stdin=subprocess.PIPE)
proc.communicate(u' '.join(cmd).encode('utf-8'))
注意我的字符串的'u'前缀,然后当我传递字符串进行通信时,我能够将自己的编码定义为utf-8。