subprocess.run()参数编码

问题描述 投票:1回答:2

我有一个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启动的。尽管在C.UTF-8警告,我已将其更改为/etc/sysconfig/httpd。这没有帮助,FS编码仍然是'ascii'。然后我甚至将sys.getfilesystemencoding()猴子修补到lambda: 'utf-8'。但错误仍然存​​在。

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

我的智慧结束了。

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

UPDATE1:

代码段:

    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)
python encoding mod-wsgi
2个回答
0
投票

在mod_wsgi的上下文中,您应确保使用mod_wsgi守护程序模式并为mod_wsgi守护程序进程组设置lang / locale。有关更详细的说明,请在此处重复,请参阅:


0
投票

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

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

  1. 文件系统编码是关键点。
  2. 猴子修补不起作用。嗯,没关系。无论如何,这是一种解决方案。
  3. LANG=C.UTF-8需要安装区域设置,它不在我的系统上(使用locale -a检查)。但是在第二个可用的系统上,它可以工作。
  4. 我可以显式地进行编码并将字节作为args之一传递: cmdresult = sub.run( [SCRIPT, tid, days, name.encode('utf-8')], ...

这是有效的,但有一个问题是:

它符合文档吗?

我能找到的是:

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

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

expected str, bytes or os.PathLike object

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

© www.soinside.com 2019 - 2024. All rights reserved.