10

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

7
  • 8
    execve() arg 3 is the environment. Are you sure the env parameter you are passing only contains strings? Commented Nov 3, 2012 at 21:37
  • Yes, I am positive. That was the first thing I checked. Commented Nov 3, 2012 at 21:38
  • 10
    I'm not sure, but I believe that at least 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. Commented Nov 3, 2012 at 21:44
  • I have not tried that, I'll see if that's the issue. Commented Nov 3, 2012 at 21:45
  • Hey thanks! The help is much appreciated! It runs as expected now! Commented Nov 3, 2012 at 21:51

3 Answers 3

8

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

Sign up to request clarification or add additional context in comments.

Comments

2

I ran into a similar problem. In my case, the problem was because I was just passing python native types in the dictionary I passed to env. This could actually be consistent with what the OP, given the level of information here. Consider the point where

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

is called. If environ looked like

{"variable": True}

Then the True in there would almost certainly be the cause of the error. You can use the string (bytestring, as per the other answer) "true" in its place.

Comments

2

in my case, the environment variables's value was a number. treating the value as string with quoting was my soluction as the error message, execve() arg 3 contains a non-string value.

from

- env:
  - VARIABLES: 1

to

- env:
  - VARIABLES: "1"

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.