【问题标题】:running a cmd file with an accented character in its name, in Python 2 on Windows在 Windows 上的 Python 2 中运行名称中带有重音字符的 cmd 文件
【发布时间】:2017-09-03 21:07:40
【问题描述】:

我在 Windows 上有文件 t2ű.cmd,其名称中有一个重音字符,我想从 Python 2 代码运行它。

如果我将文件名作为 unicode 文字传递,则打开文件 (open(u't2\u0170.cmd')) 有效,但 str 文字无效,因为 \u0170 不在 Windows 的代码页上。 (有关打开名称中带有重音字符的文件的更多信息,请参阅此问题:opening a file with an accented character in its name, in Python 2 on Windows。)

在没有 Python 的情况下从命令提示符运行文件。

我尝试将 str 文字传递给 os.systemos.popenos.spawnlsubprocess.call(无论有无外壳),但它无法找到该文件。

这些不起作用,它们会引发 UnicodeDecodeError: 'ascii' codec can't encode character u'\u170'...

  • os.system(u't2\u170.cmd')
  • os.popen(u't2\u170.cmd')
  • os.spawnl(u't2\u170.cmd', u't2')
  • subprocess.call(u't2\u170.cmd')
  • subprocess.call(u'"t2\u170.cmd"')
  • subprocess.call([u't2\u170.cmd'])

在这个项目中升级到 Python 3 是不可行的。

重命名文件是不可行的,因为这些文件可以在只读共享上具有任意(用户提供的)名称,并且目录名称也可以包含重音字符。

在 C 语言中,我会使用 <process.h> 中的任何 wsystemwpopenwspawnl 函数。

最好我正在寻找一种适用于标准 Python 模块的解决方案(无需安装包)。但我对任何解决方案都感兴趣。

我需要一个不打开新窗口的解决方案。

最终我想将命令行参数传递给程序,参数将包含任意 Unicode 字符。

【问题讨论】:

  • 尝试改用os.startfile,查看 Python 源代码 (2.7.14rc1),在我看来它支持 Unicode 字符串。如果做不到这一点,我想你可以使用 ctypes 显式调用 CreateProcessW。
  • @HarryJohnston,这可能就足够了,因为看起来 pts 不需要命令行参数。另请注意,os.startfile 不会等待获取退出代码,它会创建一个新的控制台,该控制台将在批处理脚本退出后立即销毁。否则,选项是使用 ctypes (如您所说)或创建扩展模块。 PyWin32 的 win32process 模块在这里没有用,因为它也在 Python 2 中调用 CreateProcessA
  • 感谢您对os.startfilewin32processCreateProcessW 的澄清。看起来没有什么现成的可用(除了使用 ctypes 手动编码),它在 Python 2 中调用 CreateProcessW。如果你写一个关于这个的答案,我会接受它。

标签: windows unicode python-2.x popen


【解决方案1】:

这是基于@eryksun 的评论。

我们需要调用系统调用CreateProcessW或C函数wspawnlwsystemwpopen。 Python 2 没有内置任何可以调用这些函数的东西。用 C 语言编写扩展模块或使用 ctypes 调用函数可能是一种解决方案。

C 函数 CreateProcessAspawnlsystempopen 不起作用。

【讨论】:

    【解决方案2】:

    pep 0263中所述,如果您想在python脚本中使用unicode字符,只需在脚本开头添加# -*- coding: utf-8 -*-即可(在she-bang之后就可以了):

    #!/bin/env python
    # -*- coding: utf-8 -*-
    import os
    
    os.system('t2ű.cmd')
    

    如果你仍然发现问题,你可以看看一些包,比如win-unicode-console

    它现在应该可以直接工作了,没有转义代码。

    【讨论】:

    • 感谢您的帮助。您的建议不起作用,我仍然收到此错误:UnicodeDecodeError: 'ascii' codec can't encode character u'\u170'...。同样,它也不适用于os.system(u't2\u0170.cmd'.encode('utf-8'))。请注意,在 Python 中创建 U+0170 字符不是我的问题,我知道该怎么做,而且它有效。问题中概述了我的问题。
    • 我认为问题在于您仍试图在编码声明之后将转义码放入 unicode 字符串中。看看官方guide
    • 您也尝试过其他路线,例如os.system(u't2\u0170'.encode("<encoding>")),您可以通过>>>sys.stdout.encoding找到<encoding>
    • 我刚刚检查了 Python 2 源代码,据我所知,os.system() 只调用了 CreateProcess 的 ASCII 版本,所以除非你可以在当前代码中对字符串进行编码代码页我认为你不走运。我不清楚sys.stdout.encoding(终端的编码)是否始终与当前代码页相同。
    • @oldMammuth:我确定我正确使用了 Unicode 转义:open(u't2\u0170.cmd').read() 正确返回了文件的内容。但是,os.system(u't2\u0170.cmd')os.system(u't2\u0170.cmd'.encode('utf-8')) 或任何其他编码都不起作用,因为 U+0170 不是当前代码页的一部分。我需要一个无需更改代码页的解决方案,因为我希望能够运行具有任意名称的脚本。
    猜你喜欢
    • 2018-02-12
    • 1970-01-01
    • 2018-03-26
    • 2015-07-01
    • 2017-02-01
    • 1970-01-01
    • 2018-09-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多