- remote SSH shell on macOS does not use
/etc/paths - this is not an issue of ansible, it is the way macOS processes config files on remote shells:
- see
ssh localhost echo \$PATH
- ...if not specified otherwise and macOS does not read any startup files
- example:
[...]localhost '/bin/sh -c '"'"'sudo -H -S -n -u test /bin/sh -c '"'"'"'"'"[...] - even
/bin/bashdoes not read any startup files by default
- see
man sh
... When invoked as an interactive shell with the name
sh,bashlooks for the variableENV, expands its value if it is defined, and uses the expanded value as the name of a file to read and execute....
- and
When
bashis started non-interactively, to run a shell script, for example, it looks for the variableBASH_ENVin the environment, expands its value if it appears there, and uses the expanded value as the name of a file to read and execute.
echo "localhost" > inventory
ansible localhost -a 'echo $PATH'
- you will see the full path of current shell
ansible -c ssh -i inventory localhost -a 'echo $PATH'
- you will see the standard
PATH=/usr/bin:/bin:/usr/sbin:/sbin
ansible -b --become-user=test -c ssh -i inventory localhost -a 'echo $PATH'
- no change, still only the default path
- add
BASH_ENV=~/.profileinto the environment of the playbook/role, - unfortunately that does not work with ad-hoc commands, so we need a playbook
- simple playbook
test_env_playbook.yml
---
- name: Test ENV
hosts: localhost
environment:
BASH_ENV: "~/.profile"
# also possible, but not using hosts config PATH: "{{ ansible_env.PATH }}:/usr/local/bin"
tasks:
- name: Echo PATH
shell: echo $PATH
args:
executable: /bin/bash
become: yes
become_user: "test"
- run it (very verbose)
ansible -i inventory test_env_playbook.yml -vvv
.profileor.bash_profileor.bash_rcare not read by default, neither are system wide config filesENVis not used when executed with/bin/sh, although it says so inman bashBASH_ENVis loaded when executable is/bin/bash- ansible
commandmodule always uses/bin/shso you need to use theshellmodule - --> set
BASH_ENVto either global/etc/profileor user~/.profileas desired
- I create a
~/.profileon the root and user accounts - I load defaults from my user profile:
echo 'source /etc/profile' >> ~/.profile - Benefit: I can use for example python/pip installed in my user
Librarydirectory - Downside: the ansible
pipmodule does not work if its installed in/usr/local/binfolder, so you need to use theshellmodule.- To make the
pipmodule work again, you have to usePATHenvironment for the role
- To make the
Thank you for your effort. My solution on this - just hardcode the environment globally in a playbook. (
BASH_ENVdidn't work for me for some reason)Pros - it works. Cons - you must exactly know which PATH you're trying to achieve.
For basic stuff like rbenv, homebrew (w/ Apple Silicon
/opt/supported paths) I have setup below