软连接
这个可以在 /usr/bin 目录中找到:
(base) jetson@ubuntu:~$ cd /usr/bin/
(base) jetson@ubuntu:/usr/bin$ ls python*
python python2.7 python2-config python3.8 python3.8-coverage python3-config python3-futurize python-argcomplete-check-easy-install-script3
python2 python2.7-config python3 python3.8-config python3.9 python3-coverage python3-pasteurize python-argcomplete-tcsh3
其中的 python 和 python3 都可能是软连接,具体链接到哪里可以用下述命令查看:
(base) jetson@ubuntu:/usr/bin$ ls -l python
lrwxrwxrwx 1 root root 7 Apr 15 2020 python -> python3
(base) jetson@ubuntu:/usr/bin$ ls -l python3
lrwxrwxrwx 1 root root 9 Mar 13 2020 python3 -> python3.8
同时,也可以使用 which python 命令查看当前 shell 中实际解析到的 Python 路径:
(base) jetson@ubuntu:~$ which python
/home/jetson/anaconda3/bin/python
可以看到我的系统中,默认 Python 是 Anaconda 的。虽然 conda 的虚拟环境可以为不同类型的项目提供诸多便利,但是有些时候也会导致 C++ 代码编译出现问题。
下面先用软连接方式把 /usr/bin 目录的 Python 修改为 python2。之所以这样操作,不是说一定要这样,只是记录一下操作流程:
(base) jetson@ubuntu:/usr/bin$ sudo rm python
(base) jetson@ubuntu:/usr/bin$ sudo ln -s python2 python
(base) jetson@ubuntu:/usr/bin$ ls -l python
lrwxrwxrwx 1 root root 7 Aug 8 11:14 python -> python2
其中,ln -s 的基本格式为:
ln -s [源文件或目录] [符号链接名]
完事。
update-alternatives
如果想要修改系统的 Python,并实现相对方便的多版本管理,可以使用 update-alternatives 命令:
update-alternatives --install <链接名称> <名称> <路径> <优先级>
然后我们试一下,使用 update-alternatives --config python 即可切换 Python 命令对应的版本:
(base) jetson@ubuntu:~$ sudo update-alternatives --install /usr/bin/python python /usr/bin/python2.7 1
update-alternatives: using /usr/bin/python2.7 to provide /usr/bin/python (python) in auto mode
(base) jetson@ubuntu:~$ sudo update-alternatives --install /usr/bin/python python /usr/bin/python3.8 2
update-alternatives: using /usr/bin/python3.8 to provide /usr/bin/python (python) in auto mode
(base) jetson@ubuntu:~$ sudo update-alternatives --config python
There are 2 choices for the alternative python (providing /usr/bin/python).
Selection Path Priority Status
------------------------------------------------------------
* 0 /usr/bin/python3.8 2 auto mode
1 /usr/bin/python2.7 1 manual mode
2 /usr/bin/python3.8 2 manual mode
Press <enter> to keep the current choice[*], or type selection number: 2
这里配置的是 /usr/bin/python 这个 alternative,不会自动改变 /usr/bin/python3。也就是说,切换完成后,变化的是 Python 命令对应的解释器,而 python3 仍然会按照当前 $PATH、软链接或其他 alternatives 配置去解析。
我们检查一下:
(base) jetson@ubuntu:~$ which python
/home/jetson/anaconda3/bin/python
(base) jetson@ubuntu:~$ which python3
/home/jetson/anaconda3/bin/python3
怎么没改过来……emmm,忘了当前还在 conda 的 base 环境里。
可以使用下面这条命令,不让 Terminal 自动打开 base 环境:
conda config --set auto_activate_base false
但是这条命令只是不自动进入 base 环境,不会删除你手动写入 .bashrc 的 $PATH,也不会退出当前已经激活的环境。你可能还需要重新打开 shell,或者先执行:
conda deactivate
再看看:
jetson@ubuntu:~$ which python
/home/jetson/anaconda3/envs/py37/bin/python
jetson@ubuntu:~$ which python3
/home/jetson/anaconda3/envs/py37/bin/python3

发生甚么事了,我们打开 .bashrc 看看,发现里面有如下内容:
export PATH=/home/jetson/anaconda3/envs/py37/bin/:$PATH
export MVCAM_SDK_PATH=/opt/MVS
export MVCAM_COMMON_RUNENV=/opt/MVS/lib
export MVCAM_GENICAM_CLPROTOCOL=/opt/MVS/lib/CLProtocol
export ALLUSERSPROFILE=/opt/MVS/MVFG
# export LD_LIBRARY_PATH=/opt/MVS/lib/aarch64:$LD_LIBRARY_PATH
export PKG_CONFIG_PATH=/home/jetson/libmodbus/install/lib/pkgconfig:$PKG_CONFIG_PATH
# HKVision ARM64 SDK LIB PATH
export LD_LIBRARY_PATH=/home/jetson/libHKVision:$LD_LIBRARY_PATH
# >>> conda initialize >>>
# !! Contents within this block are managed by 'conda init' !!
__conda_setup="$('/home/jetson/anaconda3/bin/conda' 'shell.bash' 'hook' 2> /dev/null)"
if [ $? -eq 0 ]; then
eval "$__conda_setup"
else
if [ -f "/home/jetson/anaconda3/etc/profile.d/conda.sh" ]; then
. "/home/jetson/anaconda3/etc/profile.d/conda.sh"
else
export PATH="/home/jetson/anaconda3/bin:$PATH"
fi
fi
unset __conda_setup
# <<< conda initialize <<<
看第一行!谁给我加的!不会是我吧。。。
第一行的内容把 conda 环境路径手动放到了 $PATH 最前面,所以 which python 和 which python3 仍然会优先找到 /home/jetson/anaconda3/envs/py37/bin/ 里的解释器,而不是 /usr/bin 里的解释器。
把第一行注释掉,然后 source 一下:
source ~/.bashrc
再检查:
jetson@ubuntu:~$ which python
/usr/bin/python
jetson@ubuntu:~$ which python3
/usr/bin/python3
如果出现 which python3 -> /usr/bin/python 这种结果,那就说明环境里还有别的配置在影响解析结果。前面的 update-alternatives 命令只配置了 /usr/bin/python,并没有配置 /usr/bin/python3。这种情况下,可以继续检查 /usr/bin/python3 软链接、shell alias、shell hash,或者 PATH 中是否还有其他路径优先。
所以,这部分的结论是:如果已经关闭了默认打开 base 环境,并且 .bashrc 里没有手动把某个 conda 环境路径放到 PATH 最前面,那么运行 update-alternatives --install 和 update-alternatives --config python 后,就可以切换 /usr/bin/python。后面需要修改 .bashrc 文件,纯粹是我个人环境的问题。
回头看,如果只是某个项目需要特定 Python 版本,用 venv、conda 环境、脚本 shebang,或者在 CMake / 编译命令中显式指定 Python 解释器,会比全局修改系统 Python 更省心。
评论