git @ Cat's Eye Technologies Falderal / ensure-shell-text-quoted
Under 2.7, use pipes.quote instead of hand-rolled (h/t @j4james). Chris Pressey 2 years ago
1 changed file(s) with 6 addition(s) and 19 deletion(s). Raw diff Collapse all Expand all
88 unicode = unicode
99 except NameError:
1010 unicode = str
11
12 try:
13 from shlex import quote as shlex_quote
14 except ImportError:
15 from pipes import quote as shlex_quote
1116
1217 # Note: the __str__ method of all the classes defined herein should
1318 # produce a short, human-readable summary of the contents of the object,
566571 def subst(self, command, var_name, value):
567572 """Replace all occurrences of `var_name` in `command` with
568573 `value`, but make sure `value` is properly shell-escaped first."""
569
570 # We could do this with shlex.quote, but that only appeared in 3.3.
571 # To support Python 2.7, we just take every character that is a
572 # shell metacharacter, and escape it. Note that we have to handle
573 # backslashes first, lest we escape backslashes we just added in.
574
575 value = value.replace('\\', '\\\\')
576 for c in """ ><*?[]'"`$()|;&#""":
577 value = value.replace(c, '\\' + c)
578
579 # Note that, to handle putting multi-line strings into a single
580 # command line, we need to escape newlines. Note, however, that
581 # shells don't understand escape sequence like "\n"! Instead, we
582 # put an actual newline in single quotes. We do this for tabs too.
583
584 value = value.replace("\n", "'\n'")
585 value = value.replace("\t", "'\t'")
586
587 return command.replace(var_name, value)
574 return command.replace(var_name, shlex_quote(value))
588575
589576 def run(self, body=None, input=None):
590577 # first, expand all known variables in the command, using subst().