【发布时间】: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 服务。
我已经束手无策了。
- 我的问题真的是 FS 编码引起的吗?
- 如果是,为什么我尝试将其更改为 utf-8 失败?
- 最重要的是:我该如何解决这个问题?
更新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 只要求它们可以表示为 Cchar*字符串,由子进程来解码它们。 -
@DanielPryden 代码附加,
shell=False默认情况下。