moogyd <moo...@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. -- http://mail.python.org/mailman/listinfo/python-list