Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 521
Abram I Avatar asked Nov 03 '12 21:11

Abram I


People also ask

How do I get output from Popen?

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.

What is subprocess Popen in Python?

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.

How do you end a subprocess call in Python?

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.

What is PIPE in Python 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.


3 Answers

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"
like image 56
John Kang Avatar answered Oct 20 '22 20:10

John Kang


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.

like image 45
AlanSE Avatar answered Oct 20 '22 21:10

AlanSE


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

like image 8
DreadPirateShawn Avatar answered Oct 20 '22 21:10

DreadPirateShawn