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
popen. To run a process and read all of its output, set the stdout value to PIPE and call communicate(). The above script will wait for the process to complete and then it will display the output.
The subprocess module defines one class, Popen and a few wrapper functions that use that class. The constructor for Popen takes arguments to set up the new process so the parent can communicate with it via pipes. It provides all of the functionality of the other modules and functions it replaces, and more.
Popen(args) with args as a sequence of program arguments or a single string to execute a child program in a new process with the supplied arguments. To terminate the subprocess, call subprocess. Popen. terminate() with subprocess.
PIPE as either of them you specify that you want the resultant Popen object to have control of child proccess's stdin and/or stdout , through the Popen 's stdin and stdout attributes.
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"
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With