diff options
author | James Cammarata <jimi@sngx.net> | 2014-07-21 20:40:58 -0500 |
---|---|---|
committer | James Cammarata <jimi@sngx.net> | 2014-07-22 16:17:16 -0500 |
commit | b35e1a664d574efca2a4f8022fef447bf3e1661e (patch) | |
tree | 61e77e35aa99c56e28ce643079c27af47be0c2da | |
parent | 907c98ed7bd684c7d1478847b810ff352bb2f80b (diff) | |
download | ansible-b35e1a664d574efca2a4f8022fef447bf3e1661e.tar.gz |
Fixing up shell quoting issues
-rw-r--r-- | library/commands/command | 29 | ||||
-rw-r--r-- | test/integration/roles/setup_ec2/tasks/main.yml | 2 |
2 files changed, 22 insertions, 9 deletions
diff --git a/library/commands/command b/library/commands/command index 1b27f40b81..69090846f1 100644 --- a/library/commands/command +++ b/library/commands/command @@ -84,6 +84,24 @@ EXAMPLES = ''' - command: /usr/bin/make_database.sh arg1 arg2 creates=/path/to/database ''' +# This is a pretty complex regex, which functions as follows: +# +# 1. (^|\s) +# ^ look for a space or the beginning of the line +# 2. (creates|removes|chdir|executable|NO_LOG)= +# ^ look for a valid param, followed by an '=' +# 3. (?P<quote>[\'"])? +# ^ look for an optional quote character, which can either be +# a single or double quote character, and store it for later +# 4. (.*?) +# ^ match everything in a non-greedy manner until... +# 5. (?(quote)(?<!\\)(?P=quote))((?<!\\)(?=\s)|$) +# ^ a non-escaped space or a non-escaped quote of the same kind +# that was matched in the first 'quote' is found, or the end of +# the line is reached + +PARAM_REGEX = re.compile(r'(^|\s)(creates|removes|chdir|executable|NO_LOG)=(?P<quote>[\'"])?(.*?)(?(quote)(?<!\\)(?P=quote))((?<!\\)(?=\s)|$)') + def main(): # the command module is the one ansible module that does not take key=value args @@ -193,7 +211,6 @@ class CommandModule(AnsibleModule): lexer.ignore_quotes = "'" items = list(lexer) - command_args = '' for x in items: if '=' in x: # check to see if this is a special parameter for the command @@ -208,13 +225,9 @@ class CommandModule(AnsibleModule): if not (os.path.exists(v)): self.fail_json(rc=258, msg="cannot use executable '%s': file does not exist" % v) params[k] = v - else: - # this isn't a valid parameter, so just append it back to the list of arguments - command_args = "%s %s" % (command_args, x) - else: - # not a param, so just append it to the list of arguments - command_args = "%s %s" % (command_args, x) - params['args'] = command_args.strip() + # Remove any of the above k=v params from the args string + args = PARAM_REGEX.sub('', args) + params['args'] = args return (params, params['args']) main() diff --git a/test/integration/roles/setup_ec2/tasks/main.yml b/test/integration/roles/setup_ec2/tasks/main.yml index b02c758b80..c20785b998 100644 --- a/test/integration/roles/setup_ec2/tasks/main.yml +++ b/test/integration/roles/setup_ec2/tasks/main.yml @@ -17,7 +17,7 @@ # along with Ansible. If not, see <http://www.gnu.org/licenses/>. - name: generate random string - command: python -c \"import string,random; print ''.join(random.choice(string.ascii_lowercase) for _ in xrange(8));\" + command: python -c "import string,random; print ''.join(random.choice(string.ascii_lowercase) for _ in xrange(8));" register: random_string tags: - prepare |