[ACCEPTED]-Python module to shellquote/unshellquote?-quoting
try: # py3 from shlex import quote except ImportError: # py2 from pipes import quote quote("hello stack overflow's quite cool") >>> '"hello stack overflow\'s quite cool"'
gets me far enough.
pipes.quote is now
shlex.quote in python 3.
It is easy enough 2 to use that piece of code.
That version handles 1 zero-length argument correctly.
To unquote, try
I'm pretty sure that pipes.quote is broken, and 3 should not be used, because it does not 2 handle zero-length arguments correctly:
>>> from pipes import quote >>> args = ['arg1', '', 'arg3'] >>> print 'mycommand %s' % (' '.join(quote(arg) for arg in args)) mycommand arg1 arg3
I 1 believe the result should be something like
mycommand arg1 '' arg3
For shell quoting, this works: I've rigorously 4 tested it on Posix. [I'm assuming that 3 the
list2cmdline function supplied by Python works as 2 advertised on Windows]
# shell.py import os if os.name == 'nt': from subprocess import list2cmdline def quote(arg): return list2cmdline([arg]) else: import re _quote_pos = re.compile('(?=[^-0-9a-zA-Z_./\n])') def quote(arg): r""" >>> quote('\t') '\\\t' >>> quote('foo bar') 'foo\\ bar' """ # This is the logic emacs uses if arg: return _quote_pos.sub('\\\\', arg).replace('\n',"'\n'") else: return "''" def list2cmdline(args): return ' '.join([ quote(a) for a in args ])
The tests are here, if 1 anyone cares.
The standard library module subprocess has 4 the list2cmdline function which does this, albeit 3 according to Microsoft rules so I am not sure how reliable 2 it works in Unix-like environments for more 1 complicated command lines.
quotefunction is available for quite some 4 time (Python 2.7?) -- the major drawback 3 is it moved from
pipe module to
shlex between 3.2 2 and 3.3.
You have to be prepared to handle 1 both cases while importing that function:
try: from shlex import quote except ImportError: from pipes import quote
You should never have to shell quote. The 6 correct way to do a command is to not do 5 shell quoting and instead use subprocess.call or subprocess.Popen, and 4 pass a list of unquoted arguments. This 3 is immune to shell expansion.
subprocess.Popen(['echo', '"', '$foo'], shell=False)
If you 2 want to unquote shell quoted data, you can 1 use shlex.shlex like this:
list(shlex.shlex("hello stack 'overflow'\''s' quite cool"))
More Related questions