From 393909d0cc5096b1c2f7c8580f3ad5dafdff774a Mon Sep 17 00:00:00 2001 From: Andy Freeland Date: Wed, 26 Jul 2017 10:14:59 -0700 Subject: [PATCH] Add 'stdin' argument to command/shell modules Fixes #14380 #23428 --- lib/ansible/modules/commands/command.py | 10 ++++++- lib/ansible/modules/commands/shell.py | 6 ++++ .../targets/command_shell/tasks/main.yml | 29 +++++++++++++++++++ 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/lib/ansible/modules/commands/command.py b/lib/ansible/modules/commands/command.py index e9544ff8136..40dca48c7f0 100644 --- a/lib/ansible/modules/commands/command.py +++ b/lib/ansible/modules/commands/command.py @@ -49,6 +49,12 @@ options: type: bool default: 'yes' version_added: "1.8" + stdin: + version_added: "2.4" + description: + - Set the stdin of the command directly to the specified value. + required: false + default: null notes: - If you want to run a command through the shell (say you are using C(<), C(>), C(|), etc), you actually want the M(shell) module instead. The C(command) module is much more secure as it's not affected by the user's environment. @@ -121,6 +127,7 @@ def main(): creates=dict(type='path'), removes=dict(type='path'), warn=dict(type='bool', default=True), + stdin=dict(required=False), ) ) @@ -131,6 +138,7 @@ def main(): creates = module.params['creates'] removes = module.params['removes'] warn = module.params['warn'] + stdin = module.params['stdin'] if not shell and executable: module.warn("As of Ansible 2.4, the parameter 'executable' is no longer supported with the 'command' module. Not using '%s'." % executable) @@ -174,7 +182,7 @@ def main(): args = shlex.split(args) startd = datetime.datetime.now() - rc, out, err = module.run_command(args, executable=executable, use_unsafe_shell=shell, encoding=None) + rc, out, err = module.run_command(args, executable=executable, use_unsafe_shell=shell, encoding=None, data=stdin) endd = datetime.datetime.now() delta = endd - startd diff --git a/lib/ansible/modules/commands/shell.py b/lib/ansible/modules/commands/shell.py index 3ef8d52c8fe..a730828a5a7 100644 --- a/lib/ansible/modules/commands/shell.py +++ b/lib/ansible/modules/commands/shell.py @@ -60,6 +60,12 @@ options: required: false default: True version_added: "1.8" + stdin: + version_added: "2.4" + description: + - Set the stdin of the command directly to the specified value. + required: false + default: null notes: - If you want to execute a command securely and predictably, it may be better to use the M(command) module instead. Best practices when writing diff --git a/test/integration/targets/command_shell/tasks/main.yml b/test/integration/targets/command_shell/tasks/main.yml index 226f8df622f..ef96e88dd08 100644 --- a/test/integration/targets/command_shell/tasks/main.yml +++ b/test/integration/targets/command_shell/tasks/main.yml @@ -121,6 +121,35 @@ that: - "command_result4.changed != True" + +- name: pass stdin to cat via command + command: "cat" + args: + stdin: 'foobar' + register: command_result5 + +- name: assert that stdin is passed + assert: + that: + - "command_result5.stdout == 'foobar'" + +- name: send to stdin literal multiline block + command: "{{ sha1sum.stdout }}" + args: + stdin: |- + this is the first line + this is the second line + this line is after an empty line + this line is the last line + register: command_result6 + +- debug: var=command_result6 + +- name: assert the multiline input was passed correctly + assert: + that: + - "command_result6.stdout == 'b1a4df888d8d261876dc33ded211ba3ebe803010 -'" + ## ## shell ##