Hi,
I have been redirected from Github issue 56044.
I am finding that commands which work when run manually fail when run with a shell task, because the $PATH is different, so binaries such as ip and modinfo cannot be found.
Bcoca said:
In any case this is due to Ansible doing a batch login, which does not source the same files as a live login, this depends on your system’s configuration and can be changed by setting the PATH the same way for both types of logins.
What does that mean?
When I search online for batch logins, I get a whole bunch of irrelevant results about Windows Batch scripts.
Is this the batch you see with man batch
?
How can I make an Ansible shell task execute with the same $PATH as when I ssh in manually?
I am only having this problem on a Centos target, not Ubuntu. (Perhaps the PATH is modified for Ubuntu too, but it is not impacting me because Ansible’s shell task can still find the binaries I need.)
I am already telling Ansible to use bash not sh.
Detail
Steps to reproduce
I am trying to use shell
to run the modinfo
binary, and also theip
binary.
I can run the command I want manually by ssh-ing into the machine.
But when I do it with Ansible, shell
says “command not found”, because the $PATH
is different between SSH and Ansible shell
.
This happens with Ansible version 2.5 and 2.9.
My target is Centos 7.6
When I manually ssh in I see:
[centos@dell03 ~]$ which modinfo
/usr/sbin/modinfo
[centos@dell03 ~]$ echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/centos/.local/bin:/home/centos/bin
[centos@dell03 ~]$ modinfo ext4
That last command prints out a lot of text, and returns 0.
Then I try with ansible:
---
- hosts: localhost
tasks:
- name: check modinfo
shell: |
echo $PATH
which modinfo
modinfo ext4
args:
executable: /bin/bash
**Expected results:**
- task should pass
- stdout should be
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/centos/.local/bin:/home/centos/bin
followed by a lot of text about the ext4 module
i.e. shell
can find the modinfo
binary because the PATH
is the same as before.
**Actual Result**
fatal: [10.58.2.103]: FAILED! => {
"changed": true,
"cmd": "echo $PATH\nwhich modinfo\nmodinfo ext4 \n",
"delta": "0:00:00.003893",
"end": "2019-05-03 16:50:23.683406",
"invocation": {
"module_args": {
"_raw_params": "echo $PATH\nwhich modinfo\nmodinfo ext4 \n",
"_uses_shell": true,
"argv": null,
"chdir": null,
"creates": null,
"executable": "/bin/bash",
"removes": null,
"stdin": null,
"stdin_add_newline": true,
"strip_empty_ends": true,
"warn": true
}
},
"msg": "non-zero return code",
"rc": 127,
"start": "2019-05-03 16:50:23.679513",
"stderr": "which: no modinfo in (/usr/local/bin:/usr/bin)\n/bin/bash: line 2: modinfo: command not found",
"stderr_lines": [
"which: no modinfo in (/usr/local/bin:/usr/bin)",
"/bin/bash: line 2: modinfo: command not found"
],
"stdout": "/usr/local/bin:/usr/bin",
"stdout_lines": [
"/usr/local/bin:/usr/bin"
]
}
Reading the results:
echo $PATH
→ /usr/local/bin:/usr/bin
, which is not the path from before
So bash could not find the modinfo
binary.
As a workaround, I am able to manually look up where the binary I want is, then prepend "$PATH=$PATH:/usr/sbin " to my shell command. That works, but is not scalable.
tldr, how can I make the shell task use the same $PATH as a normal ssh login?
Thanks,
Matt