【问题标题】:Python: How to pass non-ASCII file names to Popen on Windows?Python:如何在 Windows 上将非 ASCII 文件名传递给 Popen?
【发布时间】:2012-08-30 01:47:26
【问题描述】:

当我使用 Python 运行子进程时,ASCII 参数的一切都很好,但如果参数是 unicode(西里尔文)字符串,则会失败:

cmd = [ 'dir.exe', u'по-русски' ]
p = subprocess.Popen([ 'dir.exe', u'по-русски' ])

错误日志:

Traceback (most recent call last):
  File "process.py", line 48, in <module>
    cyrillic()
  File "process.py", line 45, in cyrillic
    p = subprocess.Popen(cmd, shell=True, stdin=None, stdout=None, stderr=subprocess.PIPE)
  File "C:\Python\27\Lib\subprocess.py", line 679, in __init__
    errread, errwrite)
  File "C:\Python\27\Lib\subprocess.py", line 870, in _execute_child
    args = '{} /c "{}"'.format (comspec, args)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 8-10: ordinal not in range(128)

我尝试了不同的可执行文件 - 7z.ex、ls.exe - popen 在运行之前就失败了。

但是如果我将 unicode 字符串编码为特定的编码呢?

# it works because 1251 is kinda native encoding for my Windows
cmd = [ 'dir.exe', CYRILLIC_FILE_NAME.encode('windows-1251') ]

# fails because 1257 cannot be converted to 1251 without errors
cmd = [ 'dir.exe', BALTIC_FILE_NAME.encode('windows-1251') ]

# this may work but it's not a solution because...
cmd = [ 'dir.exe', BALTIC_FILE_NAME.encode('windows-1257') ]

“坏”的东西,我的电脑上有不同的文件名——波罗的海、西里尔文等等。所以看起来没有一般的方法可以在 Windows 上将非 ASCII 文件名传递给 Popen?!还是可以修复? (最好没有肮脏的黑客攻击。)

Windows 7、Python 2.7.3

【问题讨论】:

  • 我不熟悉 Python,但看起来cmd 将 ASCII 字符串与 Unicode 字符串混合在一起。当 Popen 将字符串合并在一起形成命令行时,也许这会造成麻烦?我建议您尝试将两个字符串都设为 Unicode。
  • cmd 并不是唯一的 - 问题也发生在运行 mplayer 上。使两个 args 都成为 unicode 并没有帮助。谢谢。
  • 查看文档,似乎没有任何选项可以让 Popen 使用 Unicode,因此(如果没有人有更好的答案!)您可能必须解决这个问题。编写一个使用 UTF-8 命令行,将其转换为 UTF-16,然后执行它的 C 程序会相当简单。
  • 哦,是的,Popen 不适用于 unicode。此外,它仅适用于 ASCII。 (我会用新的细节更新我最初的帖子)。

标签: windows file process python-2.7


【解决方案1】:

如果您使用 Python 3,它将正确地以 Unicode 格式传递参数。假设您的子进程可以在命令行上加载 unicode 参数(Python 2 不能),那么它应该可以工作。

例如,此脚本在 Python 3 下运行时,将显示西里尔字符。

import subprocess
subprocess.call(["powershell", "-c", "echo", "'по-русски'"])

【讨论】:

    猜你喜欢
    • 2017-09-02
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 2014-09-06
    • 2016-10-27
    • 2018-01-13
    • 2019-05-08
    相关资源
    最近更新 更多