alain at dpt-info.u-strasbg.fr
Thu Nov 4 16:55:16 CET 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'])
>>>> p = subprocess.Popen('echo $MYVAR',shell=True)
>>>> 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
> 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
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
Shell variables are explained in detail in any shell man page. The
execvp() system call has its own man page.
More information about the Python-list