N
Nick Craig-Wood
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!
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!