通过对 MSYS2 的一顿操作,可以获得在 Windows 下比较畅快的 Linux 工具的体验,体验到 Vim、Tmux、zsh、Git、MinGW-w64 等优秀的工具:

最终效果图

Windows 下的桌面端程序丰富,但是对于一个程序猿来说,在某些犄角旮旯的需求场景下用 Linux 的命令行工具解决可能比 Windows 下 GUI 的鼠标点击来的更快,在熟悉了 Linux 命令行之后更加是离不开。某些 Windows 下的收费程序(如 XShell)还能在 Linux 下找到跟好且开源的替代品(OpenSSH);而有些 Linux 下命令行工具(如 tmux)的极致体验在 Windows 下就很难得了。还好有 MSYS2 的存在,解决了 Windows 下 tmux、ssh、compiler 等众多命令行的痛点。WSL(Windows Subsystem for Linux) 结合 mintty 应该也能满足需求,有机会的话另做文章。

一些概念

在进行操作之前有必要了解下下面的几个容易混淆的名称和概念:

  • Cygwin,利用 cygwin1.dll 将 POSIX 调用转换为 Windows 的 API 调用,利用模拟层以支持将 Linux 应用移植到 Windows 上。Cygwin 提供名为 apt-cyg 的包管理。

  • MinGW,Minimalist GNU for Windows,MinGW 是用于进行 Windows 应用开发的 GNU 工具链,如可以在 VScode 中选用其作为 C/C++ 的开发工具链(也如 Code::blocks、eclipse 等),它的编译产物一般是原生 Windows 应用,MinGW 工具链也存在于 Linux、BSD 甚至 Cygwin 下。但是 MinGW 不能编译包含 MFC、WinSDK 的 Windows 应用。

  • MinGW-w64,MinGW 的 64 位版本。

  • MSYS,MinGW 仅仅是工具链,win 下的 cmd 使用起来不够方便,MSYS 是用于辅助 Windows 版 MinGW 进行命令行开发的配套软件包,提供了部分 Unix 工具以使得 MinGW 的工具使用起来方便一些。相比基于庞大的 Cygwin 下的 MinGW 会轻巧不少。

  • MSYS2,MSYS 的第二代,有大量预编译的软件包,并且具有包管理器 pacman (ArchLinux)。

  • mintty终端虚拟机,可以供 Cygwin、MSYS、MSYS2、WSL 使用,GitHub

以上的内容都可以在 Git-Credential-Manager-for-Windows 中大佬的讨论里看到。

使用 mintty

win 下的 MSYS2 和 Cygwin 都是使用的 mintty,也可以使用 cmder 或者 ConEmu 连接,但是在 ConEmu 和 cmder 下使用 tmux 体验有问题,所以还是建议使用 mintty 为好。

mintty 的使用的 Tips,可以自行研究下。

不过就使用来说了解下面的几个快捷键就可:

  • ctrl/shift + ins 复制/粘贴
  • 在 tmux 的鼠标模式下,按下 shift 还是可以使用鼠标选择文字的
  • ctrl + plus/minus/zero 放大、缩小、还原
  • 拖拽资源管理器里的文件/文件夹到 mintty 可以得到其路径

mintty 美化

可以在 这里 找到很多主题,下面给出了一个基于 onedark 主题和 DejaVu 字体(支持 Powerline) 的配置,修改 ~/.minttyrc 为下面的内容之后重新打开 mintty 即可:

 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
Font=DejaVuSansMono NF
Transparency=low
FontHeight=10
Term=xterm-256color
Columns=110
Rows=35
Scrollbar=none
AllowBlinking=yes
CursorType=block

ForegroundColour=171,178,191
BackgroundColour=30,33,39
CursorColour=97,175,239
BoldBlack=92,99,112
Black=92,99,112
BoldRed=224,108,117
Red=224,108,117
BoldGreen=152,195,121
Green=152,195,121
BoldYellow=209,154,102
Yellow=209,154,102
BoldBlue=97,175,239
Blue=97,175,239
BoldMagenta=198,120,221
Magenta=198,120,221
BoldCyan=86,182,194
Cyan=86,182,194
BoldWhite=171,178,191
White=171,178,191
BoldAsFont=yes

其他的配置也可以通过右键 mintty 窗口标题栏的 option 进行修改,也可以将主题文件保存到 msys64/usr/share/mintty/themes 目录下,这样在 option 里就可以修改了。vim 下光标不是块的问题参考block-cursor,暂时没有好的解决方法。

cmder & ConEmu

这一部分自己可以探索,在使用 tmux + zsh 之后其实可以放弃这两个软件了,除非有使用 cmd 和 powershell 的需求。

使用 Git bash

在正式进入 MSYS2 的使用之间,可以先聊聊 Windows 下大家都会安装的工具 Git for Windows,一个基于 MSYS2 的 Git。下载安装就不在赘述,我的习惯一般是只将 git bash here 勾选上。

使用 Git bash 时候从窗口标题栏可以看出这是个基于 MinGW-w64 的项目,利用 Git 的源码 和 MinGW-w64 工具链编译的基于 windows 下的 git,为了提高使用幸福感 Git bash 的 shell 使用的是 MSYS2(安装目录下的 usr/bin/mintty),当然将 git.exe 所在目录加在 windows 下的环境变量里之后在 cmd 和 powershell 下也是可以使用 git 命令的,但是其体验不及 git bash(如无:GCM)。

由于使用了 MSYS2,那么同时也会提供一些附属的命令,查看 git 安装目录下的 usr/bin 即可知道有哪些。

改进 Git bash 体验,如果不想安装 MSYS2 但又想改进 git bash 的使用姿势,可以参照下面的步骤:

  1. 使用 tmux,这个需要先安装下载 MSYS2 然后使用 pacman 安装 tmux ,之后将 tmux.exemsys-event-2-1-4.dll 放在 Git\usr\bin 目录下,可直接使用以提取的文件 msys2-tmux-pkg-for-git.zip

  2. 集成 vscode 终端,参考 MSYS2 的 vscode 终端集成,也就是将 zsh 换成 bash

git for windows 是基于 MSYS2 和 MinGW 的一个项目,但是是基于修改过的 msys2-runtime,查看 gfw wiki 可能会了解更多。如果仅仅是轻度的命令行依赖,在安装 tmux 之后,git bash 应该就能够满足需求,但如果诉求更多的话,那么就要考虑 MSYS2 了。

使用 MSYS2

下面进入正题,完全使用 MSYS2 可以在其上安装 git,MinGW-w64,OpenSSH,CMake 还有其他工具等,免得使用 git 装一个、使用 MinGW-w64 又装一个,这所以的功能其实都可以由 MSYS2 配合 pacman 来完成,OpenSSH + tmux 连什么 XShell 工具都可以省略掉了。

关于 msysgit 和 git for windows 的区别?在 msysgit 可以看到。

安装和更新

  1. 安装,在 MSYS2 官网 下载安装 MSYS2。

  2. 更新源,众所周知,使用 pacman 的默认源肯定是慢的一批,所以参考 中科大 MSYS2 源 添加上国内源。

  3. 更新软件包,执行完下面的命令之后,需要手动关闭窗口,然后在 MSYS2 的安装目录下找到 autorebase.bat,双击运行之后再打开 Msys2。完之后可能需要再执行以下第二步骤,因为自定义的源可能再更新的时候被覆盖了

    1
    2
    
    $ pacman -Sy
    $ pacman -Su
  4. 之后再次运行 pacman -Su 更新软件包

  5. 安装一些常见的包 pacman -S git vim tmux zsh rsync openbsd-netcat

  6. 参考 mintty 美化

  7. 在 windows 上配置环境变量 HOME 为 C:\you-path\msys64\home\your-name,增加这个环境变量的目的是为了让 git for windows 的 home 目录指向 MSYS2 的 home 目录;如果安装了 git for windows ,其 home 目录默认为 %USERPROFILE%,导致 git for windows 和 MSYS2 的 git 配置和 vim 等配置不能共享;如果在安装 MSYS2 之前已经安装 git for windows 需要使用将之前的 ssh 和 git 的配置拷贝到 MSYS2 的 home 目录下。

MSYS2 改造

  • vim、tmux 的配置根据自己的喜好即可,vim 下的 YouCompleteMe

  • 使用 sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)" 安装 ohmyzsh,之后要想默认打开使用 zsh 需要做下面的几步:

    • 确保以后使用 msys2.exemingw32.exemingw64.exe 打开终端,而不是 bat。
    • 修改 MSYS2 安装文件夹下的 msys2.inimingw32.inimingw64.ini 在其内加上 SHELL=/usr/bin/zsh
    • 但是在 tmux 里面还是会默认使用 bash,修改 ~/.tmux.conf 添加 set-option -g default-shell /usr/bin/zsh 然后从 reload。
  • 如果想要继承 windows 的 PATH,修改 msys2.ini 等文件添加上 MSYS2_PATH_TYPE=inherit

  • 添加右键打开,可以尝试 msys2-mingw-shortcut-menus ;实际使用中应该是开一个窗口使用 tmux 进行复用,利用鼠标拖拽到 mintty 窗口即可快速粘贴路径

  • 安装 MinGW-w64 的 gcc 工具链,使用命令 pacman -S mingw-w64-x86_64-toolchain,需要使用 mingw64.exe 打开的 shell 里才会有工具链的命令。

  • 可以将 git for windows 的环境变量去掉,然后将 msys64\usr\bin 目录添加到 windows 环境变量中,这样可以只使用 MSYS2 中的 git 了,使用之前需要修改的一个地方是需要使用命令行 git config --global core.autocrlf true 配置一下,原因是 git for windows 默认配置是 true ,即将 win 下的 crlf(carriage return, line feed) 转化为 lf 后存入版本库,但是 MSYS2 中的默认不是,所以需要配置之后使用。

  • 也可以直接在 MSYS2 上安装 64 位的 git for windwows,需要参考 Install inside MSYS2 proper,不过 gfw 在 zsh 下面好像有 compdef 的错误。

  • 可以自行挂载常用 win 下的目录到 MSYS2 的 home 目录。要想快速 cd 到某个目录,可以在 window 的文件管理将该文件夹拖动到 mintty 窗口,一般会将 D:\data\ 转为如 /d/data/ 的形式。

  • 可能使用 zsh 的默认样式,由于 git 状态获取的原因会比较慢,因为 zsh-async 在 window 下用不了,这时候可以使用 agkozak-zsh-prompt window 下可以用的异步样式。

知识点

pacman

包管理 pacman 有下列常用的参数

  • -S 同步软件,即下载
  • -Sl 列出可用软件包
  • -R 删除包
  • -Q 列出当前安装的包

MSYS2 MinGW32/64

安装完 MSYS2 之后,开始菜单中会发现三个快捷方式:MSYS2 MinGW 32-bitMSYS2 MinGW 64-bitMSYS2 MSYS,右键快捷方式发现其执行都是 msys2_shell.cmd 文件,只是附件的参数不同如 -mingw32-mingw64-msys

查看 msys2_shell.cmd 文件会发现传进来的参数会影响环境变量 MSYSTEM 的配置:

1
2
3
4
if "x%~1" == "x-msys" shift& set MSYSTEM=MSYS& goto :checkparams
if "x%~1" == "x-msys2" shift& set MSYSTEM=MSYS& goto :checkparams
if "x%~1" == "x-mingw32" shift& set MSYSTEM=MINGW32& goto :checkparams
if "x%~1" == "x-mingw64" shift& set MSYSTEM=MINGW64& goto :checkparams

当然还可以使用其他的一些参数,让其设定为环境变量传递给 MSYS2 设置其特性。

也就是这三个的不同点也就是一个环境变量的不同,而这个环境变量最终会影响 PATH 的调用顺序,也就是 mingw32 优先使用 mingw32 下的工具,mingw64_shell.bat 优先使用 mingw64 下的工具,而 msys2 两个都不使用,只用自身 msys 的工具 (usr bin)。这么做的好处是当需要编译 32bit Target 的项目时使用 mingw32,64 bit 使用 mingw64,各套工具互不干扰。

MSYS2 配置

在上面的改造之中也提及了开启 MSYS2 终端时候传递的环境变量配置,这些配置会影响最终的 SHELL 效果,可以在 *.ini 里配置相应 *.exe 的启动参数,也可以通过快捷方式传递给 msys2_shell.cmd

  • MSYSTEM 也可以修改为 MSYS2
  • MSYS2_PATH_TYPE 是否继承 windows 的 PATH 环境变量
  • CHERE_INVOKING 是否使用当前登录目录为 HOME 目录;1 为否
  • SHELL 指定 mintty 开启的终端

部分环境变量最终起作用的原理在于 /etc/profile 脚本,可以自行实践。

VSCode 集成 zsh

将 zsh 集成到 VSCode 的内置终端非常简单,一下是我的参考配置:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// 新shell尝试
"terminal.integrated.shell.windows": "C:\\Application\\msys64\\usr\\bin\\zsh.exe",
"terminal.integrated.shellArgs.windows": [
    "--login",
],
"terminal.integrated.env.windows": {
    "CHERE_INVOKING": "1",
    "MSYSTEM": "MINGW64",
    "MSYS2_PATH_TYPE": "inherit",
    "VSCODE": "1"
},
"terminal.integrated.cursorStyle": "line",
"terminal.integrated.fontFamily": "DejaVuSansMono NF",

需要说明的是 terminal.integrated.env.windows 项,这里的配置可以根据个人需要设置,值得注意的是 VSCODE 环境变量是我自己定义的,原因是在 VSCode 终端内使用默认的 robbyrussell 主题,由于提示符其提示符箭头的问题,终端内光标会不正常,问题见a space between cursor and words,我这里的解决方式是,复制修改一份 robbyrussell 的主题,将箭头换成 > 符号,然后在 ~/.zshrc 里加以判断:

1
2
3
4
5
if [[ -z "${VSCODE}" ]]; then
    ZSH_THEME="robbyrussell"
else
    ZSH_THEME="robbyrussell_fix"
fi

这样在 VSCode 里将环境变量 VSCODE 传入即可激活修改过的主题,当然如果你使用的主题没有问题就不需要这样做了。还有就是同 cmder/ConEmu 一样,在 VSCode 的集成终端内无法使用 tmux。

其他问题

修复 mintty 的使用 win 的 python 终端问题,这是因为因为宿主机上的 python 使用的是 native Windows API for command-line user interaction,也就是涉及到 win 下的关于终端输入的命令在 msys2 下都会无法进入,还好有解决方法。

安装 pacman -S winpty 作为 mintty 代理,处理 python 之外其他有问题的也可使用如 nodejs、MySQL 等。之后就可以使用如 winpty python 来使用,也可以全局使用 winpty 去 wraper,但是会使得 tmux 无法使用。所以最好的方式在 bashrc/zshrc 里添加 alias 即可:

1
2
3
4
5
6
alias mysql="winpty mysql"
alias node="winpty node"
alias python="winpty python"
alias ipython="winpty ipython"
alias psql="winpty psql"
alias redis-cli="winpty redis-cli"

另外在 msys2 下要想使用 python 虚拟环境,就得使用 source venv/Scripts/activate 的形式了。

watch 命令缺失,该命令需要单独安装:pacman -S procps-ng,同理一些其他的命令行的缺失可以在搜索引擎里以 MSYS2 xxx 的形式得到解答。下面列出常用的包:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
vim
git
tmux
tree
zsh
rsync
winpty
procps-ng
inetutils
curl
openbsd-netcat

参考