subprocess.Popen execve()arg 3包含非字符串值

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了subprocess.Popen execve()arg 3包含非字符串值相关的知识,希望对你有一定的参考价值。

我正试图通过shell运行另一个脚本,它使用一组修改过的环境变量。

def cgi_call(script, environ):
    pSCRIPT = subprocess.Popen(script, stdout=subprocess.PIPE, stderr=subprocess.PIPE, 
                        stdin=subprocess.PIPE, env=environ, shell=True)

    pc = pSCRIPT.communicate()

    status = "200 OK"
    headers = [('Content-Type',"text/html")]
    if pc[1] != '':
        raise RuntimeError, pc[1]
    else:
        rval = str(pc[0])

    return status, headers, rval

运行上面的代码后,我收到以下错误:

File "server/httpd.py", line 76, in DynamicServer
    status, headers, rval = handler(environ)
File "server/httpd.py", line 43, in handler
    status, headers, rval = cgi_call(srvpath+"../www/public_html"+environ["PATH_INFO"]+'index.py',environ)
File "server/httpd.py", line 21, in cgi_call
    stdin=subprocess.PIPE, env=environ, shell=True)
File "/usr/lib/python2.7/subprocess.py", line 679, in __init__
    errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1249, in _execute_child
    raise child_exception
<type 'exceptions.TypeError'> execve() arg 3 contains a non-string value

传递环境变量时出现错误...我也尝试将它们作为字符串传递 - 它出错并说它需要一个映射对象。然而,事实上,通过的环境是一个映射对象......

问题是什么?

附加信息:我在Ubuntu 12.04.1上运行Python 2.7

答案

复制评论中的答案,以便从“未答复”过滤器中删除此问题:

“...... Python 2.x中的键,也可能是值,也需要是字节串。所以如果你使用unicode字符串,请确保将它们编码为utf-8。另外,如果你默认使用unicode文字通过from __future__ import unicode_literals确保字典键的字符串文字以b为前缀,以字节文字而不是unicode文字。“

〜每Pedro Romano回答

另一答案

我遇到了类似的问题。在我的情况下,问题是因为我只是在传递给env的字典中传递python本机类​​型。考虑到这里的信息水平,这实际上可以与OP一致。考虑一下这一点

cgi_call(srvpath+"../www/public_html"+environ["PATH_INFO"]+'index.py',environ)

叫做。如果environ看起来像

{"variable": True}

然后那里的True几乎肯定会成为错误的原因。您可以使用字符串(bytestring,根据其他答案)"true"代替它。

以上是关于subprocess.Popen execve()arg 3包含非字符串值的主要内容,如果未能解决你的问题,请参考以下文章

subprocess的popen函数

python subprocess.popen stdin.write

subprocess.Popen("echo $HOME"... 和 subprocess.Popen(["echo", "$HOME"]

python subprocess.Popen

从 subprocess.Popen 调用“源”命令

subprocess.Popen 和缓冲的进程输出