Popen Question

Alain Ketterlin alain at dpt-info.u-strasbg.fr
Thu Nov 4 11:55:16 EDT 2010


moogyd <moogyd at yahoo.co.uk> writes:

>>>> import os, subprocess
>>>> os.environ['MYVAR'] = "myval"
>>>> p = subprocess.Popen(['echo', '$MYVAR'],shell=True)
>>>>
>>>> p = subprocess.Popen(['echo', '$MYVAR'])
>>>> $MYVAR
>
>>>> p = subprocess.Popen('echo $MYVAR',shell=True)
>>>> myval
>
>>>> p = subprocess.Popen('echo $MYVAR')
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
>   File "/usr/lib64/python2.6/subprocess.py", line 595, in __init__
>     errread, errwrite)
>   File "/usr/lib64/python2.6/subprocess.py", line 1106, in
> _execute_child
>     raise child_exception
> OSError: [Errno 2] No such file or directory
>
> I am not really sure I understand these results.
> 1) No idea what is going on
> 2) As (1). What isn't myval printed out (rather than $MYVAR)
> 3) Works as I wanted it to
> 4) Why do I need shell=True ?

Expanding $MYVAR into its value is a feature of the shell (afaik all
shells use the same syntax). Popen without shell=True uses the execvp()
system call directly, without going through the shell variable expansion
process (cases 2 and 4 above). For example, case 4 above asks execvp to
(find and) execute a program named "echo $MYVAR" (an 11-letter name,
where the fifth letter is space and the sixth is $ -- a perfectly valid
file/program name).

Then, if you use shell=True with a list, only the first word is used as
a command, and the others are kept in positional parameters. That's why
your first try fails (try 'sh -c echo $HOME' in a shell, without the
single quotes, and you'll get empty output).

> The documentation isn't very clear to me (it seems you need to
> understand the underlying system calls).

You're probably right. The base fact here is: the use of variables is a
feature of the shell. No shell, no variable.

> Can anyone explain (or provide link) for this behaviour in simple
> English?

Shell variables are explained in detail in any shell man page. The
execvp() system call has its own man page.

-- Alain.



More information about the Python-list mailing list