屏蔽 Msys2 终端的 Python

本文最后更新于 2026年4月1日 下午

前言

Msys2 虽说好用,终端体验类似 Linux 终端,而且有个 pacman 包管理器方便装许多软件包,但总有一些坑在里面,比如 Msys2 中的 Python 调用优先级比原 Windows 系统中安装的 Python 优先级高(被这问题恶心的好久)。下面就介绍一种方法解决这个问题吧。

坑点

先来看看 Msys2 中的 Python 是在哪里坑的。一开始我在系统中安装了一个 Python 3.11,在 Msys2 终端中可以调用这个 Python。

1
2
$ python --version
Python 3.11.8

这没什么问题,能正常调用已经安装的 Python 3.11。但在某一天为了使用 Hexo,用 pacman 命令安装了 NodeJS。

1
pacman -S mingw-w64-ucrt-x86_64-nodejs

安装完成后就去配置 Hexo 的东西了,但在安装 NodeJS 的过程中,pacman 把 Python 3.12 安装上了(不是很懂为什么 Python 要作为 NodeJS 的依赖)。

直到某一天我使用 Python 时就发现了不对劲,就用命令看了下 Python 版本。

1
2
$ python --version
Python 3.12.11

欸,我不是安装的 Python 3.11 吗,怎么变成 Python 3.12 了?想了想,用which python命令看了下 Python 调用的路径,发现居然在/ucrt64/bin/python

怎么会是呢,Msys2 怎么多给我整了个别的 Python,于是就用 pacman 查了一下,果然多了一个 Python。

1
2
3
$ pacman -Q | grep python
mingw-w64-ucrt-x86_64-python 3.12.11-1
mingw-w64-ucrt-x86_64-python-packaging 25.0-1

解决思路

既然多装了 Python,那卸载掉就好了嘛,呃…

1
2
3
4
5
6
7
$ pacman -R mingw-w64-ucrt-x86_64-python
正在检查依赖关系...
错误:无法准备事务处理 (无法满足依赖关系)
:: 删除 mingw-w64-ucrt-x86_64-python 破坏依赖 'mingw-w64-ucrt-x86_64-python' (mingw-w64-ucrt-x86_64-gdb 需要)
:: 删除 mingw-w64-ucrt-x86_64-python 破坏依赖 'mingw-w64-ucrt-x86_64-python' (mingw-w64-ucrt-x86_64-glib2 需要)
:: 删除 mingw-w64-ucrt-x86_64-python 破坏依赖 'mingw-w64-ucrt-x86_64-python' (mingw-w64-ucrt-x86_64-nodejs 需要)
:: 删除 mingw-w64-ucrt-x86_64-python 破坏依赖 'mingw-w64-ucrt-x86_64-python' (mingw-w64-ucrt-x86_64-python-packaging 需要)

诶诶,卸不掉了。

按照 Shell 查找可执行文件的方式,会在 PATH 环境变量中按顺序查找 PATH 中的路径,找到可执行文件后立即执行,所以把系统中安装的 Python 3.11 的路径置于 PATH 环境变量内的最前面就行了吧,这个方法可以。

哦,另有一个办法,既然 Shell 可能会去找 Msys2 的 Python 可执行文件,那把可执行文件改个名让 Shell 找不到就好了嘛,这样问题就解决了。

给可执行文件改个名吧

写个自动执行的函数,把 Msys2 的 Python 找到,再重新命名,这样就不会再调用那 Msys2 的 Python 了。

打开终端后,用命令新建一个 sh 文件来编写函数吧。

1
touch "${HOME}/custom_cmd.sh"

运行后会在 /home/YourUserName 这个路径新建一个 custom_cmd.sh 文件(这里要注意一下,Msys2 的 home 目录是在安装这个终端的路径中的哦),用 Visual Studio Code 打开这个文件吧,把下面的函数粘贴进去。

  1. 在 Msys2 中可以通过 cygpath 命令查看 home 目录对应的 Windows 真实路径,用法是cygpath -w "<要查看的路径>",比如查看 home 目录的真实路径:
1
cygpath -w "${HOME}"
  1. 下面的函数我只在 Bash 和 Zsh 上测试过,如果 Msys2 用的是其他终端就不知道能不能用了,不能用的话用 AI 修一下就好了吧。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# 处理 Msys2 的 Python 二进制文件
process_msys2_python_bin() {
local msys2_type_list=("clang64" "clangarm64" "mingw32" "mingw64" "ucrt64" "usr")
local python_module_type_list=("python" "pip" "pythonw")
local process_type="${*-block}"
local search_prefix
local zsh_options

# 终端类型不是 Msys2 / MinGW / CygWin 时中断运行
case "${OSTYPE}" in
msys*|cygwin*|mingw*)
;;
*)
return 1
;;
esac

# 根据处理类型设置查找关键字
case "${process_type}" in
block)
search_prefix="exe"
;;
restore)
search_prefix="exe.bak"
;;
*)
echo "未知操作类型"
return 1
;;
esac

# 在 Zsh 中屏蔽匹配不到文件的错误
if [[ "${SHELL##*/}" == "zsh" ]]; then
zsh_options=($(setopt))
setopt NULL_GLOB
fi

# 搜索可执行文件路径
for bin_type in "${msys2_type_list[@]}"; do
for python_module_type in "${python_module_type_list[@]}"; do
for bin_path in "/${bin_type}/bin/${python_module_type}"*."${search_prefix}"; do
# 跳过不是文件的匹配值
[[ ! -f "${bin_path}" ]] && continue

# 重命名文件名后缀
case "${process_type}" in
block)
mv -f "${bin_path}" "${bin_path}.bak"
;;
restore)
mv -f "${bin_path}" "${bin_path%.bak}"
;;
esac
done
done
done

# 恢复 Zsh 的原有配置
if [[ "${SHELL##*/}" == "zsh" ]]; then
unsetopt NULL_GLOB
setopt ${zsh_options} 2> /dev/null
fi
}


# 屏蔽 Msys2 的 Python 二进制文件
block_msys2_python_bin() {
process_msys2_python_bin block
}


# 恢复 Msys2 的 Python 二进制文件
restore_msys2_python_bin() {
process_msys2_python_bin restore
}


block_msys2_python_bin # 直接调用命令, 这样在每次启动终端时都会运行这个命令, 将 Msys2 的 Python 屏蔽

粘贴后保存一下就行了。此时需要知道此时的终端用的是 Bash,Zsh 或者是其他的终端解释器,就用下面的命令去查看吧。

1
echo "${SHELL##*/}"

如果显示的是 bash,则配置文件是 .bashrc;如果显示的是 zsh,则配置文件是 .zshrc,显示的是其他的话就自己在 Google 上查找吧,应该都能查到的。一般配置文件都在 /home/YourUserName 这个路径里,没找到对应的配置文件就自己创建一个吧。

然后打开这个配置文件,在配置文件里写下初始化刚刚编写函数的文件的命令。

1
. "${HOME}/custom_cmd.sh"

保存一下,再重启一下终端。现在再试试检查 Python 是不是能调用系统中已安装的了。

1
2
$ python --version
Python 3.11.8

这下正常了呢。如果想要恢复 Msys2 的 Python,运行一下restore_msys2_python_bin命令就行了(不过下次启动终端时 custom_cmd.sh 会被执行一次,里面的block_msys2_python_bin命令就会运行,把 Msys2 的 Python 屏蔽了),运行block_msys2_python_bin就可以再次屏蔽。


屏蔽 Msys2 终端的 Python
https://licyk.netlify.app/2025/06/26/block-msys2-python/
作者
licyk
发布于
2025年6月26日
许可协议