Skip to content

adhoc: clarify how the command module handles variables - #4078

Open
fjvbn2003 wants to merge 1 commit into
ansible:develfrom
fjvbn2003:adhoc-command-variables
Open

fjvbn2003 wants to merge 1 commit into
ansible:develfrom
fjvbn2003:adhoc-command-variables

Conversation

@fjvbn2003

Copy link
Copy Markdown
SUMMARY

The note in "Introduction to ad hoc commands" says:

The command module does not support extended shell syntaxes like piping and redirects (although shell variables will always work).

The part in parentheses is not accurate. The command module does not run a shell. AnsibleModule.run_command expands the arguments itself with os.path.expandvars and os.path.expanduser (module_utils/basic.py), and since ansible-core 2.16 this is controlled by the module option expand_argument_vars (default true). The module documentation already describes this: "environment variables are resolved via Python, not shell, see expand_argument_vars and are left unchanged if not matched."

So environment variables such as $HOME work, but:

  • a variable that is not set stays in the argument as $NAME (a shell would replace it with an empty string);
  • shell parameters and expansions such as $$, $RANDOM or ${VAR:-default} are passed to the command literally.

This PR rewords the note to say this and points to expand_argument_vars.

ISSUE TYPE
  • Docs Pull Request
COMPONENT NAME

docs/docsite/rst/command_guide/intro_adhoc.rst

ADDITIONAL INFORMATION

Checked with ansible-core 2.16.3 (Ubuntu 24.04 package) and ansible-core 2.21.5 (run from the v2.21.5 tag), Python 3.12, against localhost. Both versions give the same output:

$ ansible localhost -c local -m command -a 'echo HOME=$HOME BRACED=${HOME} RANDOM=$RANDOM DEFAULT=${UNSET_VAR:-fallback} PID=$$ UNSET=$UNSET_VAR'
HOME=/root BRACED=/root RANDOM=$RANDOM DEFAULT=${UNSET_VAR:-fallback} PID=$$ UNSET=$UNSET_VAR

$ ansible localhost -c local -m shell -a '<same command>'
HOME=/root BRACED=/root RANDOM= DEFAULT=fallback PID=104 UNSET=

And in a playbook with ansible-core 2.21.5:

- ansible.builtin.command:
    argv: [echo, "HOME=$HOME", "UNSET=$UNSET_VAR"]
# -> HOME=/root UNSET=$UNSET_VAR
- ansible.builtin.command:
    argv: [echo, "HOME=$HOME"]
    expand_argument_vars: false
# -> HOME=$HOME

This change was drafted with AI assistance and reviewed by me.

🤖 Generated with Claude Code

The note in the ad hoc guide says that "shell variables will always
work" with the command module. The command module does not use a shell.
It expands environment variables itself with os.path.expandvars on the
managed node, controlled by the expand_argument_vars option. Variables
that are not set stay in the argument unchanged, and shell-only syntax
such as $$ or ${VAR:-default} is passed literally.

Reword the note to describe this and point to expand_argument_vars.

Assisted-by: Claude Opus 5.5
Signed-off-by: YoungjuKim <[email protected]>
@ansible-documentation-bot ansible-documentation-bot Bot added the new_contributor This PR is the first contribution by a new community member. label Oct 16, 2026
@ansible-documentation-bot

Copy link
Copy Markdown
Contributor

Thanks for your Ansible docs contribution! We talk about Ansible documentation on Matrix at #docs:ansible.im if you ever want to join us and chat about the docs! We meet on Matrix every Tuesday. See the Ansible calendar for meeting details. We welcome additions to our weekly agenda items too. You can add the dawgs-meeting tag to a forum topic to bring it up at the next meeting.

This branch was previously deployed

1 inactive deployment
github-bot — 50ff2adf Deployed Oct 16, 2026 by fjvbn2003 via Label Issue/PR #6240
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

new_contributor This PR is the first contribution by a new community member.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant