Python subprocess.run()参数编码
我有一个Flask应用程序(Linux、带mod_wsgi的Apache、Python3),它使用一些参数调用shell脚本。当Python subprocess.run()参数编码,python,encoding,mod-wsgi,Python,Encoding,Mod Wsgi,我有一个Flask应用程序(Linux、带mod_wsgi的Apache、Python3),它使用一些参数调用shell脚本。当subprocess.run()命令参数中存在任何非ascii字符时,应用程序中会发生以下错误: “ascii”编解码器无法对位置5-6中的字符进行编码:序号不在 射程(128) 我花了很多时间试图修复它 命令行中不存在此类问题,仅在应用程序中存在 整个应用程序的输出是Unicode的,没有任何问题。经过一些研究,我得出结论,问题在于“文件系统编码” 我在run.wsg
subprocess.run()
命令参数中存在任何非ascii字符时,应用程序中会发生以下错误:
“ascii”编解码器无法对位置5-6中的字符进行编码:序号不在
射程(128)
我花了很多时间试图修复它
命令行中不存在此类问题,仅在应用程序中存在
整个应用程序的输出是Unicode的,没有任何问题。经过一些研究,我得出结论,问题在于“文件系统编码”
我在run.wsgi
脚本中添加了一些日志语句。FS编码实际上是“ascii”(命令行中是“utf-8”)
在下一步中,我找到了这篇文章
apachehttpd服务器是在其环境中使用LANG=C
启动的。尽管在/etc/sysconfig/httpd
中有警告,我还是将其更改为C.UTF-8
。这没有帮助,FS编码仍然是“ascii”。然后,我甚至将sys.getfilesystemencoding()
修补到lambda:'utf-8'
。但错误仍然存在
每次更改后,我都正确地重新启动了httpd服务
我束手无策
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)
在mod_wsgi的上下文中,您应该确保使用mod_wsgi守护进程模式,并为mod_wsgi守护进程进程组设置lang/locale。有关此处无法重复的更详细解释,请参阅:
- 文件系统编码是关键
- 猴子修补不起作用。好吧,没关系。无论如何,这是不可接受的解决办法
要求安装区域设置,但它不在我的系统上(使用LANG=C.UTF-8
locale-a检查)。但在第二个系统上,它是可行的
- 我可以显式进行编码,并将字节作为参数之一传递:
cmdresult = sub.run( [SCRIPT, tid, days, name.encode('utf-8')], ...
这是可行的,但有一个问题需要回答:
是否符合文件要求
我能找到的只是:
args应该是程序参数序列,或者是单个字符串
我确实把它理解为一个字符串或字符串列表,但实际上它没有指定什么类型的列表。我也通过了和int来看看会发生什么。我得到了这个错误:
- (回答自己的问题,希望能对他人有所帮助)
我做了一个简短的测试程序。这就是我发现的:
应为str、bytes或os.PathLike对象
所以我的解决方案似乎很好。您是否使用
shell=True
进行调用?您是以字符串还是列表的形式传递参数?请显示正在使用子流程
模块的实际代码。在操作系统级别,exec()
和朋友们不关心传递给子流程的参数使用什么编码:POSIX只要求它们可以表示为Cchar*
字符串,由子进程来解码它们。@DanielPryden Code追加,默认情况下,shell=False
。我几天前读了你关于deamon模式的博客,并将从嵌入式模式到守护模式的更改放在了我的列表的首位。谢谢你写这些博客。关于这个问题,我认为它与mod\u wsgi
关系不大。我找到了一个Python解决方案。