0%

MSYS2-Windows下的类Unix环境

生命不息,折腾不止。

最近感觉Linux越用越顺手了,尤其是Linux下的shell(此处可以特指一下目前正在用的zsh…)甩了Windows的cmd好多条街。

我平时在Windows下也经常用命令行,之前装了个Git for Windows之后,里面自带的ls/ssh/grep等等基本上已经成了我Windows下常用的命令了。

以前没怎么注意,昨天看了下Git for Windows本身就是用MSYS环境搭的,想想干脆装一个完整的MSYS2好了。

介绍

MSYS是基于MinGW开发的一个类Unix环境,MinGW可以认为是Windows下的GNU环境,也是一直以来我就在Dev和Code::Blocks上面用的东西。感觉是相当于在Windows下面用MinGW把Linux下GNU写的东西再实现一遍。

相对的,还有个Unix环境叫cygwin,比起MSYS来说cygwin更接近正常的Linux,它是依靠一个中间层把Posix调用转换成Windows的API,就像一个虚拟机一样。可能运行速度会慢一点,不过已经跟普通的Linux没什么区别了,而MSYS可能会弱很多。

问题是MinGW和MSYS更新得比较慢,然后就有人开发了MSYS2,它是fork了cygwin比较新的开发版,然后用MinGW重新实现了一部分内容而成,保持了MSYS的轻巧,同时功能上也不比cygwin弱多少。

更加重要的是,MSYS2用pacman作为包管理器!这个对于一个刚转到Arch Linux,然后逐渐开始习惯Arch的环境的人来说简直就是送上门来的好事。

更多详细介绍,详见知乎上的这个问题:

开始折腾

MSYS2的官网居然是搭在github pages上面的,跟我的博客一样,一看这地址就觉得亲切了。

下载安装包,然后装上。

打开msys的shell之后首先升级一下pacman,然后就可以愉快地Syu了。

1
2
$ pacman -Sy pacman
$ pacman -Syu

看到pacman这个熟悉的指令,感觉更亲切了~

Syu可能需要多次,第一次的时候升级了文件系统等等工具软件,结束后需要直接关闭shell软件然后重启继续更新。

然后把常用的一些东西都装上:

1
$ pacman -S git zsh vim

把MSYS目录中的usr/bin加到环境变量里面去,在正常的cmd下面就也能跑其中的软件了。

装好vim之后可以把软件源改成科大的。

zsh

MSYS自带的几个exe文件都是生成好的,默认用的是bash,我试了下正常打开之后找不到Linux下chsh等等命令,因此需要在启动mintty的时候直接加上使用zsh的参数。

MSYS目录下提供了几个bat和cmd的脚本,用于添加环境和启动shell。

直接修改start_shell.cmd,找到startmintty下面启动的参数,把bash改成zsh即可。之后要使用msys2_shell.bat这个脚本来启动MSYS的环境。

为了能在win+R窗口中直接打开MSYS,我给msys2_shell.bat脚本做了个软链接,win+X+a管理员权限启动cmd窗口,然后切到MSYS的usr/bin目录里面:

1
c:\msys64\usr\bin> mklink msys.bat c:\msys64\msys2_shell.bat

这样就创建了一个名字是msys.bat的软链接,由于上面已经把usr/bin加到系统环境变量中了,现在可以在win+R的窗口中直接输入msys就能正常打开MSYS的shell了。

有个问题是在cmd下输入msys的话,会跳出来:

1
'"c:\msys64\usr\bin\start_shell.cmd"' 不是内部或外部命令,也不是可运行的程序或批处理文件。

这样的东西。
看来这两个的执行机制稍微有点区别啊,感觉还是怪怪的,让人不太舒服,等等想办法解决一下。

或者直接在cmd里面输入zsh --login即可打开加载了完整环境内容的zsh。

SHELL变量

打开MSYS时,想用echo $SHELL输出shell信息时是空的,需要改改把信息加上去。编辑/etc/profile文件,找到:

1
2
3
4
elif [ ! "x${ZSH_VERSION}" = "x" ]; then
HOSTNAME="$(/usr/bin/hostname)"
profile_d zsh
PS1='(%n@%m)[%h] %~ %% '

在这个if语句里面加上SHELL=\which zsh``即可。

Linux中的软链接“ln -s”

然后是MSYS因为受到Windows机制的影响,默认使用ln -s做软链接的时候直接就变成复制了,也需要在/etc/profile文件里面加上一个关键变量:

1
export MSYS="winsymlinks:lnk"

之后ln -s就正常了。

访问其他目录

在MSYS里面查看当前的文件系统是这样的:

1
2
3
4
$ df -h
Filesystem Size Used Avail Use% Mounted on
C:/msys64 100G 76G 24G 77% /
D: 832G 715G 117G 86% /d

MSYS的安装目录作为当前Linux环境的根目录,然后我的D盘挂在/d下面。在这样的环境中,Linux的挂载命令就非常好用了,建个文件夹然后直接用mount把目标目录挂上去就可以了,比如C盘:

1
2
$ mkdir ~/c
$ mount c:/ ~/c

即可。

刚才作了个死,吓出一身冷汗。
测试挂载的时候刚好也在试软链接,然后一下忘了c这个文件夹是C盘的挂载点了,还以为是软链接就直接rm -rf下去了…
还好C盘里面的东西MSYS没有权限,所以它只删掉了自己的安装目录…删掉了自己的安装目录…自己的安装目录…安装目录!!!!
只好卸了重装了一遍MSYS

以后用rm命令一定要特别特别特别小心!!!

右键添加“在此打开MSYS2”选项

win+R输入regedit打开注册表管理器,在[HKEY_CLASSES_ROOT\Directory\Background\shell]下新建一个项,命名为msys2,值的内容是“Open MSYS2 Here”;

[HKEY_CLASSES_ROOT\Directory\Background\shell\msys2]下新建一个项,命名为command,值的内容是“c:\msys64\msys2_shell.bat”

shift+右键菜单里面本来也就有一个打开cmd的选项,用那个感觉更方便一点,把需要加载的环境变量内容直接写在.zshrc里面,然后在cmd中不加--login选项运行zsh就好。