Search code examples
pythonenvironment-variablespopensubprocess

subprocess.Popen execve() arg 3 contains a non-string value


I'm trying to trying to run another script via the shell, that uses a modified set of environment variables.

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

After running the code above, I get the following error:

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

The error comes when passing the environment variables... I've also tried passing them as a string - It errors out and says that it needs a mapping object. However, as it is, the environ being passed IS a mapping object...

What is the problem?

Additional Information: I am running Python 2.7 on Ubuntu 12.04.1


Solution

  • Copying the answer from the comments in order to remove this question from the "Unanswered" filter:

    "...the keys, and possibly the values also, in Python 2.x need to be byte strings. So if you are using unicode strings, make sure you encode them to utf-8. Also, if you are using unicode literals by default via from __future__ import unicode_literals make sure your string literals for the dictionary keys are prefixed with b to be byte literals instead of unicode literals."

    ~ answer per Pedro Romano