subprocess.Popen 命令(反词)在 shell 与 Web 应用程序中产生不同的输出

2023-12-08

我让 Django 在标准 WSGI/Apache httpd 组合上运行。

我注意到当我在 shell 中运行代码与在浏览器中运行代码时,文件输出是不同的。我已经隔离了其他所有内容,但仍然遇到同样的问题。

这是代码:

def test_antiword(filename):
    import subprocess
    with open(filename, 'w') as writefile:
        subprocess.Popen(["antiword", '/tmp/test.doc'], stdout=writefile)
    p = subprocess.Popen(["antiword", '/tmp/test.doc'], stdout=subprocess.PIPE)
    out, _ = p.communicate()
    ords = []
    for kk in out:
        ords.append(ord(kk))
    return out, ords

def test_antiword_view(request):
    import HttpResponse
    return HttpResponse(repr(test_antiword('/tmp/web.txt')))

在浏览器中打开 url 时,输出如下:

('\n“我说了美好的一天,先生。美好的一天!”Sh\xe9rlo\xe7k H\xf8lme\xa3 喊道。\n\n “为什么不是 Zoidberg?”Zoidberg 询问。\n', [10, 34, 73 , 32, 115, 97, 105, 100, 32, 103, 111, 111, 100, 32, 100, 97, 121, 32, 115, 105, 114, 46, 32, 71, 111, 111, 100, 32 , 100, 97, 121, 33, 34, 32, 115, 104, 111, 117, 116, 101, 100, 32, 83, 104, 233, 114, 108, 111, 231, 107, 32, 72, 248 , 108, 109, 101, 163, 46, 10, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 34, 87, 104, 121, 32 , 110, 111, 116, 32, 90, 111, 105, 100, 98, 101, 114, 103, 63, 34, 32, 113, 117, 101, 114, 105, 101, 100, 32, 90, 111 , 105, 100, 98, 101, 114, 103, 46, 10])

这是我调用时对应的输出test_antiword('/tmp/shell.txt')内壳:

('\n\xe2\x80\x9c我说美好的一天先生。美好的一天!\xe2\x80\x9d 喊着 Sh\xc3\xa9rlo\xc3\xa7k H\xc3\xb8lme\xc2\xa3。\n\n \xe2 \x80\x9c为什么不是Zoidberg?\xe2\x80\x9d 查询了Zoidberg。\n', [10, 226, 128, 156, 73, 32, 115, 97, 105, 100, 32, 103, 111, 111, 100 , 32, 100, 97, 121, 32, 115, 105, 114, 46, 32, 71, 111, 111, 100, 32, 100, 97, 121, 33, 226, 128, 157, 32, 115, 104 ,111、117、116、101、100、32、83、104、195、169、114、108、111、195、195、167、32、72、72、195、195、195、184、108、108、101、101、194、194、194、194、194、194、163 , 46, 10, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 226, 128, 156, 87, 104, 121, 32, 110, 111 , 116, 32, 90, 111, 105, 100, 98, 101, 114, 103, 63, 226, 128, 157, 32, 113, 117, 101, 114, 105, 101, 100, 32, 90, 111 , 105, 100, 98, 101, 114, 103, 46, 10])

正如您所看到的,输出非常不同。一方面,shell 输出保留了原始文件中的空格;它在网络版本中丢失了。

正如您在代码中看到的,我还将文档输出到文件中。生成的输出如下:

web.txt

"I said good day sir. Good day!" shouted Sh?rlo?k H?lme?.

             "Why not Zoidberg?" queried Zoidberg.

外壳.txt

“I said good day sir. Good day!” shouted Shérloçk Hølme£.

             “Why not Zoidberg?” queried Zoidberg.

网页版无法识别字符,编码通过file如 ISO-8859。 shell版本下,字符显示正确,编码识别为file作为 UTF-8。

我不知道为什么会发生这种情况。我已经检查过,两个进程都使用相同版本的反词。此外,我已经验证它们都使用相同的 python 模块文件subprocess。两种情况下使用的 Python 版本也完全匹配。

谁能解释一下可能发生了什么?


差异可能是由于环境变量造成的。根据man page:

Antiword 使用环境变量LC_ALL, LC_CTYPE and LANG(按顺序)获取当前区域设置并使用此信息选择默认映射文件。

我怀疑发生的情况是,当您从 shell 运行它时,您的 shell 处于 UTF-8 语言环境,但是当您从 Django 运行它时,它处于不同的语言环境,并且无法正确转换 Unicode 字符。运行子进程时尝试切换到 UTF-8 语言环境,如下所示:

new_env = dict(os.environ)  # Copy current environment
new_env['LANG'] = 'en_US.UTF-8'
p = subprocess.Popen(..., env=new_env)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

subprocess.Popen 命令(反词)在 shell 与 Web 应用程序中产生不同的输出 的相关文章

随机推荐