【问题标题】:subprocess.run() argument encodingsubprocess.run() 参数编码
【发布时间】:2017-12-22 18:57:52
【问题描述】:

我有一个 Flask 应用程序(Linux、带有 mod_wsgi 的 Apache、Python 3),它调用带有一些参数的 shell 脚本。当subprocess.run() 命令参数中有任何非ascii 字符时,应用程序中会出现以下错误:

'ascii' 编解码器无法对位置 5-6 中的字符进行编码:序数不在 范围(128)

我花了很多时间试图修复它。

命令行中不存在此类问题,仅在应用程序中存在。

整个应用程序的输出都是 Unicode 格式,没有任何问题。经过一番研究,我得出结论,问题出在“文件系统编码”上。

我在run.wsgi 脚本中添加了一些日志记录语句。 FS 编码确实是“ascii”(在命令行中是“utf-8”)。

在下一步中,我找到了这篇文章 How to change file system encoding via python?

Apache httpd 服务器在其环境中以LANG=C 启动。尽管/etc/sysconfig/httpd 中有警告,但我已将其更改为C.UTF-8。那没有帮助,FS编码仍然是'ascii'。然后我什至将sys.getfilesystemencoding() 修补到lambda: 'utf-8'。但是错误仍然存​​在。

每次更改后我都正确地重新启动了 httpd 服务。

我已经束手无策了。

  1. 我的问题真的是 FS 编码引起的吗?
  2. 如果是,为什么我尝试将其更改为 utf-8 失败?
  3. 最重要的是:我该如何解决这个问题?

更新1:

代码sn-p:

    import subprocess as sub
    cmdresult = sub.run(
        [SCRIPT, tid, days, name],
        stdin=sub.DEVNULL, stdout=sub.PIPE, stderr=sub.DEVNULL,
        encoding='ascii', # 'utf-8' will not help, this affects stdin, stdout I/O only
        check=True)

【问题讨论】:

  • 您是否使用shell=True 调用?您是将参数作为字符串还是列表传递?请显示使用subprocess 模块的实际代码。
  • 在操作系统级别,exec() 和朋友们并不关心传递给子进程的参数使用什么编码:POSIX 只要求它们可以表示为 C char* 字符串,由子进程来解码它们。
  • @DanielPryden 代码附加,shell=False 默认情况下。

标签: python encoding mod-wsgi


【解决方案1】:

(回答自己的问题,希望对其他人有所帮助)

我做了一个简短的测试程序。这是我发现的:

  1. 文件系统编码是关键。
  2. 猴子补丁不起作用。好吧,没关系。无论如何,它是不可接受的解决方案。
  3. LANG=C.UTF-8 需要安装语言环境,但它不在我的系统上(通过 locale -a 检查)。但在可用的第二个系统上,它可以工作。
  4. 我可以明确地进行编码并将字节作为参数之一传递:

    cmdresult = sub.run(
        [SCRIPT, tid, days, name.encode('utf-8')],
        ...
    

这可行,但有一个问题:

它是否符合文档?

我只能找到:

args 应该是一系列程序参数,或者是单个字符串

我确实将它理解为一个字符串或一个字符串列表,但实际上它并没有指定一个什么类型的列表。我也通过了 int 看看会发生什么。我收到了这个错误:

expected str, bytes or os.PathLike object

所以我的解决方案似乎很好。

【讨论】:

    【解决方案2】:

    在 mod_wsgi 的上下文中,您应该确保您使用的是 mod_wsgi 守护进程模式,并为 mod_wsgi 守护进程组设置语言/语言环境。更详细的解释在此不再赘述,请参阅:

    【讨论】:

    • 几天前我刚刚阅读了您关于守护程序模式的博客,并将从嵌入式到守护程序模式的更改放在我的列表中。感谢您撰写这些博客。关于这个问题,我觉得和mod_wsgi关系不大。我找到了一个 Python 解决方案。
    猜你喜欢
    • 2018-10-28
    • 2020-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-12
    • 1970-01-01
    • 2017-07-26
    • 2015-11-11
    相关资源
    最近更新 更多