subprocess.run()参数编码
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了subprocess.run()参数编码相关的知识,希望对你有一定的参考价值。
我有一个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服务。
我的智慧结束了。
- 我的问题真的是由FS编码造成的吗?
- 如果是,为什么我尝试将其更改为utf-8失败了?
- 最重要的是:我该如何解决这个问题?
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)
在mod_wsgi的上下文中,您应确保使用mod_wsgi守护程序模式并为mod_wsgi守护程序进程组设置lang / locale。有关更详细的说明,请在此处重复,请参阅:
(回答自己的问题,希望对别人有帮助)
我做了一个简短的测试程序。这是我发现的:
- 文件系统编码是关键点。
- 猴子修补不起作用。嗯,没关系。无论如何,这是一种解决方案。
LANG=C.UTF-8
需要安装区域设置,它不在我的系统上(使用locale -a
检查)。但是在第二个可用的系统上,它可以工作。- 我可以显式地进行编码并将字节作为args之一传递:
cmdresult = sub.run( [SCRIPT, tid, days, name.encode('utf-8')], ...
这是有效的,但有一个问题是:
它符合文档吗?
我能找到的是:
args应该是一系列程序参数或者是一个单独的字符串
我确实把它理解为一个字符串或一个字符串列表,但实际上并没有指定什么类型的列表。我也通过了int来看看会发生什么。我收到了这个错误:
expected str, bytes or os.PathLike object
所以我的解决方案似乎很好。
以上是关于subprocess.run()参数编码的主要内容,如果未能解决你的问题,请参考以下文章
如何在 python 中使用 subprocess.run() 运行 step-cli