sdbbs
sdbbs

Reputation: 5468

Python get path to actual Python executable?

Using cygwin on Windows 10. When I type this on the cygwin bash shell:

$ python --version
Python 3.8.10

... I get that the default Python I have is 3.8. However, what - or where - is the actual executable, that is being called? That is a bit more difficult to find explicitly; say, which tells me:

$ which python
/usr/bin/python

... but if I look closer:

$ ls -la /usr/bin/python*
lrwxrwxrwx 1 user None    24 Oct  1 14:06 /usr/bin/python -> /etc/alternatives/python
lrwxrwxrwx 1 user None    13 Oct  1 14:04 /usr/bin/python2 -> python2.7.exe
-rwxr-xr-x 1 user None  9235 Jan  2  2021 /usr/bin/python2.7.exe
-rwxr-xr-x 1 user None  1685 Jan  2  2021 /usr/bin/python2.7-config
lrwxrwxrwx 1 user None    16 Oct  1 14:05 /usr/bin/python2-config -> python2.7-config
lrwxrwxrwx 1 user None    25 Oct  1 14:06 /usr/bin/python3 -> /etc/alternatives/python3
lrwxrwxrwx 1 user None    14 Oct  1 14:04 /usr/bin/python3.6 -> python3.6m.exe
-rwxr-xr-x 1 user None 10259 May  5 13:22 /usr/bin/python3.6m.exe
-rwxr-xr-x 1 user None  9747 May 20 12:07 /usr/bin/python3.8.exe

So, it turns out /usr/bin/python is actually a symlink to /etc/alternatives/python, which is a small binary file with XML contents (EDIT: Wrong, see below); so it is not the Python interpreter executable.

Of course, I can already now guess that the executable is most likely /usr/bin/python3.8.exe - however, I'd like to get this answer explicitly from Python itself.

But, if I do this:

$ python -c 'import sys; print(sys.executable)'
/usr/bin/python

... I get again /usr/bin/python as an answer, which is just a symlink to something else, and therefore not the actual executable.

Is there a way to retrieve the absolute path to the actual Python interpreter executable from Python itself?


EDIT: it turns out /etc/alternatives/python3 is a symlink to the actual interpreter:

$ ls -al /etc/alternatives/python3
lrwxrwxrwx 1 user None 18 Oct  1 14:06 /etc/alternatives/python3 -> /usr/bin/python3.8

... but still, I'd like to know if there is a way for Python itself to tell me this.

Upvotes: 2

Views: 6164

Answers (3)

Mortz
Mortz

Reputation: 4939

On Linux / Unix - there is the readlink command which follows the symlink. You can invoke that from within python using the os module -

import os
cmd_out = os.popen("readlink -f `which python`")
cmd_out.read()

Upvotes: 0

Corralien
Corralien

Reputation: 120549

Use os.path.realpath

import os
import sys

print(os.path.realpath(sys.executable))

Or

python -c 'import sys, os; print(os.path.realpath(sys.executable))'

Upvotes: 6

juanpa.arrivillaga
juanpa.arrivillaga

Reputation: 96277

You should be able to resolve symlinks using pathlib, something like:

import sys
from pathlib import Path

executable = Path(sys.executable).resolve()

Nowadays, I always use pathlib.Path objects to handle paths.

Alternatively, if you prefer the older API, you can still use os.path, so

import os.path
executable = os.path.realpath(sys.executable)

Upvotes: 4

Related Questions