I would try cleaning it up manually. I've never done this so make sure you backup beforehand.
- Remove the link from /etc/alternatives
- Remove the relevant file from the admin directory
- /var/lib/dpkg/alternatives/ on ubuntu (debian may be the same but check the man pages under the FILES section)
- /var/lib/alternatives/ on CentOS 6&7
I would try cleaning it up manually. I've never done this so make sure you backup beforehand.
- Remove the link from /etc/alternatives
- Remove the relevant file from the admin directory
- /var/lib/dpkg/alternatives/ on ubuntu (debian may be the same but check the man pages under the FILES section)
- /var/lib/alternatives/ on CentOS 6&7
Removing them manually resulted in ... is already managed by ... error in my case. Aside from that, the manual removal also didn't scale, as i've had added multiple multiple alternatives for the centralized symlink. It's just a mess.
When it comes to either update-alternatives or alternatives, they both provide the --remove and --remove-all flags. As for the former flag, it only removes one single alternative of the link group. For example
$ update-alternatives --list python3
/usr/bin/python3.8
/usr/bin/python3.9
$ sudo update-alternatives --remove python3 /usr/bin/python3.9
$ update-alternatives --list python3
/usr/bin/python3.8
The form of the --remove flag goes by
update-alternatives --remove symlink-generic-name /path/to/one/executable/alternative
However, if you want to outright erase the generic name with all of its associated alternatives all at once, then --remove-all is the way to go.
$ update-alternatives --list python3
/usr/bin/python3.8
/usr/bin/python3.9
$ sudo update-alternatives --remove-all python3
$ update-alternatives --list python3
update-alternatives: error: no alternatives for python3
$ update-alternatives --query python3
update-alternatives: error: no alternatives for python3
replace
[bash:~] $ sudo update-alternatives --install /usr/bin/python python \
/usr/bin/python2.7 2
[bash:~] $ sudo update-alternatives --install /usr/bin/python python \
/usr/bin/python3.5 3
with
[bash:~] $ sudo update-alternatives --install /usr/local/bin/python python \
/usr/bin/python2.7 2
[bash:~] $ sudo update-alternatives --install /usr/local/bin/python python \
/usr/bin/python3.5 3
e.g. installing into /usr/local/bin instead of /usr/bin.
and ensure the /usr/local/bin is before /usr/bin in PATH.
i.e.
[bash:~] $ echo $PATH
/usr/local/bin:/usr/bin:/bin
Ensure this always is the case by adding
export PATH=/usr/local/bin:$PATH
to the end of your ~/.bashrc file. Prefixing the PATH environment variable with custom bin folder such as /usr/local/bin or /opt/<some install>/bin is generally recommended to ensure that customizations are found before the default system ones.
Per Debian policy, python refers to Python 2 and python3 refers to Python 3. Don't try to change this system-wide or you are in for the sort of trouble you already discovered.
Virtual environments allow you to run an isolated Python installation with whatever version of Python and whatever libraries you need without messing with the system Python install.
With recent Python 3, venv is part of the standard library; with older versions, you might need to install python3-venv or a similar package.
$HOME~$ python --version
Python 2.7.11
$HOME~$ python3 -m venv myenv
... stuff happens ...
$HOME~$ . ./myenv/bin/activate
(myenv) $HOME~$ type python # "type" is preferred over which; see POSIX
python is /home/you/myenv/bin/python
(myenv) $HOME~$ python --version
Python 3.5.1
A common practice is to have a separate environment for each project you work on, anyway; but if you want this to look like it's effectively system-wide for your own login, you could add the activation stanza to your .profile or similar.
Will installing multiple Python versions break system tools?
Why would I need multiple Python versions on Rocky Linux 8?
Solution: Use dnf for official RPM packages or pyenv for fine-grained version control.
What’s the safest way to install additional Python versions without conflicts?
Official RPMs (Best for stability):
sudo dnf module install python39 # For Python 3.9
pyenv (Best for flexibility):
https://pyenv.run | bash # Installs pyenv
pyenv install 3.11.4 # Downloads and compiles Python 3.11.4
Manual compilation (Advanced users):
Download source from python.org and install to /usr/local/.
Avoid replacing /usr/bin/python3—system tools depend on it!
Add python2.6 to alternatives:
sudo alternatives --install /usr/bin/python python /usr/local/bin/python2.6 5
Then set python3.9 as defaut:
sudo alternatives --config python
Or override the symlink with the desired python version:
sudo ln -fs /usr/bin/python3.9 /usr/bin/python
Late to the party but to me the good practice for this is to run
sudo alternatives --install /usr/bin/python3 python3 /bin/python3.9 99
Since you are trying to update the alternatives for python 3.x version it makes sense to use the python3 link instead of the python one.
After installing the alternative, configure it with:
sudo alternatives --config python3
And in the end:
sudo alternatives --config python
To configure the python link to point to python3 using alternatives
You are definitely able to do an "n to n" link as you state, just add the python3 group symlink you created as a potential target to python:
alternatives --install /usr/bin/python python /usr/bin/python3 300
alternatives --set python /usr/bin/python3
Each --install command will add or update an alternative, which you can see with alternatives --display python
Try update-alternatives --config python and update the current selection using the arrow keys. This gives the option to set the default python version.