Running Python script, running into /usr/bin/env: No such file or directory

Hi All,

Basically, I’m trying to run a python script on a host. I have a playbook that’s using the script module and it works when I target Oracle Enterprise Linux 6.7. However, trying it against a Solaris host fails. This is peculiar to me because I can copy the python script to the Solaris box and run it no problem. Running the script targeting the Solaris host with the ansible-playbook command gets me:

TASK [Running script on host] **************************************************

fatal: [hostnamehere.whatever.com]: FAILED! => {“changed”: true, “failed”: true, “rc”: 127, “stderr”: “”, “stdout”: “/usr/bin/env: No such file or directory\r\n”, “stdout_lines”: [“/usr/bin/env: No such file or directory”]}

So basically, no such file or directory? I’m assuming the “/usr/bin/env” is from the first line of the Python script:

#!/usr/bin/env python

Which, from my understanding is supposed to make sure to use whatever Python is applicable as Python can be installed in different paths. If Ansible can’t find it, what can I do?

When I do an echo $PATH on the Solaris host I can see /usr/local/bin/ and Python on the Solaris box is /usr/local/bin/python (Python also works when I just type ‘python’ on the Solaris host). So I tried changing the script’s first line to:

#!/usr/local/bin/python

And now it can run (but now breaks when I run it on the Oracle Enterprise Linux box). Not really sure what else I can do asides from point to different scripts with different first lines in the python script.

Hoping someone can shine some light on how I can implement this elegantly, thanks!

Ansible attempts to execute in a non interactive manner to avoid a slew of errors, part of this can affect the environment loaded, in many cases .bashrc or similar files are not loaded.

After fact gathering, use this to find out what the environment that Ansible sees is:

  • debug: var=ansible_env

Really appreciate your reply, it’s very informative. I’m still not so familiar with Ansible so it’s good to get someone else’s take.

I put that debug line into the Playbook and got the following output:

Non-Solaris
“ansible_env”: {
“CVS_RSH”: “ssh”,
“G_BROKEN_FILENAMES”: “1”,
“HOME”: “/home/admin_name_here”,
“LANG”: “en_US.UTF-8”,
“LC_ALL”: “en_US.UTF-8”,
“LC_MESSAGES”: “en_US.UTF-8”,
“LESSOPEN”: “||/usr/bin/lesspipe.sh %s”,
“LOGNAME”: “admin_name_here”,
“MAIL”: “/var/mail/admin_name_here”,
“PATH”: “/usr/local/bin:/bin:/usr/bin”,
“PWD”: “/home/admin_name_here”,
“PYTHONPATH”: “”,
“SELINUX_LEVEL_REQUESTED”: “”,
“SELINUX_ROLE_REQUESTED”: “”,
“SELINUX_USE_CURRENT_RANGE”: “”,
“SHELL”: “/bin/bash”,
“SHLVL”: “2”,
“SSH_CLIENT”: “REDACTED”,
“SSH_CONNECTION”: “REDACTED”,
“SSH_TTY”: “/dev/pts/0”,
“TERM”: “vt100”,
“USER”: “admin_name_here”,
“_”: “/usr/bin/python”
}

Solaris
“ansible_env”: {
“HOME”: “/export/home/solaris_admin_name_here”,
“LANG”: “en_US.UTF-8”,
“LC_ALL”: “en_US.UTF-8”,
“LC_MESSAGES”: “en_US.UTF-8”,
“LOGNAME”: “solaris_admin_name_here”,
“MAIL”: “/var/mail//solaris_admin_name_here”,
“PATH”: “/usr/bin:/bin”,
“PWD”: “/export/home/solaris_admin_name_here”,
“PYTHONPATH”: “”,
“SHELL”: “/usr/bin/bash”,
“SHLVL”: “1”,
“SSH_CLIENT”: “REDACTED”,
“SSH_CONNECTION”: “REDACTED”,
“SSH_TTY”: “/dev/pts/5”,
“TERM”: “vt100”,
“TZ”: “UTC”,
“USER”: “solaris_admin_name_here”,
“_”: “/bin/sh”
}

I’ve bolded the PATH for clarity. For the Non-Solaris box, Python is in /usr/bin/ which is in the PATH. However, for Solaris, only /usr/bin and /bin are there, when it looks like I need something like ‘/usr/local/bin/’ (for /usr/local/bin/python). I’m thinking this might be the issue?

Do you know if it’s possible to add to the PATH in Ansible’s non-interactive run somehow? I do have a ghetto workaround where I check the ansible_distribution and make a conditional in the playbook to point to a different script depending on the distro but it’s an ugly implementation I think. Thanks for replying!

Long time since I work on Solaris, but IIRC you can change PATH in /etc/default/login.

Thanks for the reply Kai! I took a look at the /etc/default/login file on the Solaris box and it looks like the PATH lines are commented out:

PATH sets the initial shell PATH variable

I'm pretty sure that hard coded values is in use if PATH isn't set in /etc/default/login.

Ansible is just using the environment given by the OS when it logs in over ssh.
On Linux, PAM is set to read the /etc/environment(and some other files depending on distribution) when you login with ssh, on Solaris it's /etc/default/login.

Try to set the PATH and see what happens.