1

This has tripped me up quite a lot.

The following is foo.py:

#!/usr/bin/env python

import sys
print(sys.executable)

Can someone explain the following results from running the following commands in bash?

~$ bash --version
GNU bash, version 5.0.17(1)-release (x86_64-slackware-linux-gnu)
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
~$ ./foo.py
/usr/bin/python
~$ unset PATH
~$ ./foo.py

~$ PATH=
~$ ./foo.py

03:03:35 ~$ export PATH=""
03:03:42 ~$ ./foo.py
/usr/bin/env: ‘python’: No such file or directory
3
  • You just exported an empty PATH which is where your executables are found, are you expecting something else? Commented Jun 23, 2020 at 6:34
  • The question is not obvious. But the question was about how come python executes despite the 'unset' PATH. When PATH is empty the python script is not executed by 'env'. Commented Jun 23, 2020 at 7:01
  • Yeah, sorry, I should have formulated better, but it's as @agathodaimon said. Commented Jun 23, 2020 at 7:22

1 Answer 1

4

So env uses 'execvp' (see man execvp), it's from glibc within env.c from the GNU coreutils.

Quoting from the man page:

The execlp(), execvp(), and execvpe() functions duplicate the actions of the shell in searching for an executable file if the specified filename does not contain a slash (/) character. The file is sought in the colon-separated list of directory pathnames specified in the PATH environment variable. If this variable isn't defined, the path list defaults to the current directory followed by the list of directories returned by confstr(_CS_PATH). (This confstr(3) call typically returns the value "/bin:/usr/bin".)

it is possible to verify this with 'ltrace':

$ ltrace -o env ls

execvp(0x ... etc.

Python's sys.executable also relies on the PATH variable. Which is "unset" [not there] in the situation where execvp is run with no PATH variable in the environment:

sys.executable

A string giving the absolute path of the executable binary for the Python interpreter, on systems where this makes sense. If Python is unable to retrieve the real path to its executable, sys.executable will be an empty string or None.

References:

Sign up to request clarification or add additional context in comments.

2 Comments

Why is execvp observed through ltrace but not through strace?
OK, execvp is a library call to glibc, which in turn does system calls to execve

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.