subprocess.run()参数编码

时间:2017-12-22 18:57:53

标签: python encoding mod-wsgi

我有一个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. 最重要的是:我该如何解决这个问题?
  4. 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)
    

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

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

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

  1. 文件系统编码是关键点。
  2. 猴子补丁不起作用。嗯,那没关系。无论如何,它都不能作为解决方案。
  3. LANG=C.UTF-8需要安装区域设置,并且它不在我的系统上(使用locale -a检查)。但是在第二个可用的系统上,它可以工作。
  4. 我可以明确地进行编码并将字节作为args之一传递:

    cmdresult = sub.run(
        [SCRIPT, tid, days, name.encode('utf-8')],
        ...
    
  5. 这是有效的,但有一个问题再次出现:

    是否符合文档?

    我能找到的只有:

      

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

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

    expected str, bytes or os.PathLike object

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