1

In /bin, I ran:

$ ls -l python3
lrwxrwxrwx 1 root root 10 Aug 8 01:44 python3 -> python3.12
$ python3 --version
Python 3.12.3
$ python3.12 --version
Python 3.12.5

Can anyone explain why one is "Python 3.12.3" and the other is "Python 3.12.5" when they are symlinked?

Laurel
  • 141

3 Answers3

3

To find out where they are running from, you can use:

which python3 python3.12

EDIT: As @muru mentioned, you should use type as it's a shell builtin, POSIX compliant command:

type python3 python3.12
1

When you type a command, your shell will look it up in each directory in $PATH, in the order listed, and execute the first one it finds.

For instance, if you type zorglub and your $PATH contains /usr/local/bin:/usr/bin:/bin, then:

  • Your shell will check if /usr/local/bin/zorglub exists and is executable. If is the case, it will execute that, and stop there.
  • Otherwise, it will try /usr/bin/zorglub
  • Then it will try /bin/zorglub
  • And if all fail, then it will return an error.

You can check the value of $PATH by typing

echo $PATH

$PATH is colon-separated, and it set (and often added to) in your shell startup scripts.

The result you get (what seems to be the same command returning different versions) means you probably have another python3 and/or python3.12 in some directory other than /bin, which is different version from that in /bin. The usual possible locations may include /usr/bin, /usr/local/bin, /opt/local/bin, and quite a few more depending on your environment.

For instance, your $PATH could be set to /usr/local/bin:/usr/bin:/bin and /usr/local/bin contains a python3 which is (directly or indirectly) version 3.12.3, and since /usr/local/bin is first, python3 without qualification will execute that one rather than the one in /bin. On the other hand, if python3.12 exists only in /bin, it will fall back to that version, which is 3.12.5. Or the other way around.

which python3 and which python3.12 will tell you which one is run when you type python3 and python3.12, respectively.

If you want to execute specifically the python3 or python3.12 in /bin, you need to either:

  • Have your current working directory as /bin, and run ./python3 or ./python3.12 (they should yield the same result as one is a symlink to the other)
  • Specify the full path: /bin/python3 or /bin/python3.12
  • Or make sure that there is no python3 or python3.12 in any directory listed before /bin in your $PATH.

When you have different package managers, or have a mix of software installed by package managers and via manual installation, it is sadly quite common to end up with software installed in different locations, and this can cause all sorts of problems, especially if one python script then runs another python script through the shell for some reason.

In the case of python (and many others), this is compounded by the fact that each version of the executable may use a different path for python packages. Your python package manager (pip) may also have multiple versions installed in different locations and pointing to different places. It can quickly become a bit of a mess, with pip install telling you something is installed and up to date while python tells you it's not. It's a good idea to make sure all version of python have been installed by the same means (either your distro's package manager or manual installation), not a mix of the two.

jcaron
  • 1,257
-2

If your python3 code starts with:

# /usr/bin/env python3

then your code will automatically be executed with python3.12.

If you decide to update to, say, python3.15, then all you have to do is update the python3 link to point to python3.15. Then all your code will be running 3.15.

If you have problems with the 3.15 version, you can change the link back to point to the known-good python3.12 without having to change any of your code.