Python 子进程 stdin=subprocess.PIPE 和 unicode

标签 python unicode utf-8 subprocess

好的,一些背景故事。我正在为我的应用程序编写备份和恢复功能。我想允许他们的备份文件的加密密码允许任何 unicode 字符。然后我不得不使用 subprocess 来实际运行备份命令,它可以正常使用:

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 实例。这些都不起作用。

我可以使用另一个标准输入对象来定义编码吗?请帮忙。

最佳答案

好的...我现在将停止子进程上的私刑。这完全是我不小心在 python 2 中混合使用 unicode 和 str 类型。

当将列表传递给 check_call() 命令时,它似乎有一些功能可以在向操作系统发出命令之前对所有 unicode 进行编码。当使用 communicate() 时,它需要一个字符串,但是将列表中的 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。

关于Python 子进程 stdin=subprocess.PIPE 和 unicode,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34184539/

相关文章:

Python 语法错误 : Non-UTF-8

python - 在 csv 中查找重复项和重复项的唯一性

python - 如何使用 googletrans 在 Python 中翻译 Pandas 系列?

python - wxPython 等价于 Tkinter .after()

Python UTF8 字符串混淆

Python,file(1) - 为什么数字 [7,8,9,10,12,13,27] 和范围 (0x20, 0x100) 用于确定文本文件与二进制文件

python - 如何从python中的字典数据中删除unicode字符

python - 从Python unicode字符串中获取UTF-8字符代码

python pisa utf8问题

python - 在 Python 中组织列表列表