Avoiding shell metacharacters in os.popen

David Fraser davidf at sjsoft.com
Thu Sep 30 18:10:35 CEST 2004


Nick Craig-Wood wrote:
> I'm trying to avoid using shell metacharacters in os.popen in a portable
> fashion.
> 
> os.popen() only seems to take a string as the command which would need
> tricky quoting.
> 
> os.popen2() can take a string or a list - the relevant code in Unix
> python (in popen2.py) being...
> 
>     def _run_child(self, cmd):
>         if isinstance(cmd, basestring):
>             cmd = ['/bin/sh', '-c', cmd]
>         for i in range(3, MAXFD):
>             try:
>                 os.close(i)
>             except OSError:
>                 pass
>         try:
>             os.execvp(cmd[0], cmd)
>         finally:
>             os._exit(1)
> 
> This is perfect behaviour as far as I'm concerned - if you pass a list
> it doesn't go through the shell and if you pass a string it does.
> 
> eg
> 
>   w, r = os.popen2(["ls", "-l"])
>   r.read()
> 
> This leads on to my questions :-
> 
> 1) is this behaviour (string vs list) of popen2 intentional?  Its not
> documented anywhere and it doesn't work under Windows (gives
> "TypeError: popen2() argument 1 must be string, not list")
> 
> 2) is there anything similar for os.popen() planned?
> 
> 3) is there an equivalent to the perl quotemeta() command.  This
> quotes meta-characters in a string for use in the shell.  Here is a
> suitable definition for Unix, but I don't think that \ quoting works
> in Windows
> 
>    cmd = re.sub(r"(\W)", r"\\\1", cmd)
> 
> Avoiding shell metacharacter attacks is a must for secure programs.
> Python does pretty well with its os.exec* and os.spawn* functions, but
> seems to be lacking in the os.popen* department!
> 
> Any insights appreciated!
> 

I can't exactly remember the details but I now I've had painful 
experiences on Windows trying to do this kind of thing. It seems to mess 
up quoting parameters / exe file names

David



More information about the Python-list mailing list