WSL 是Windows Subsystem for Linux 的简称,主要是为了在Windows 10上原生运行Linux二进制可执行文件(ELF格式),而提供的兼容层。 通俗来说是在Windows10 嵌入了个Linux子系统(默认是ubuntu),方便运行大部分 Linux 命令及软件,好比grep
MySQL
Apache
。这很大方便了使用Windows作开发的同窗,不须要双系统或虚拟机了。c++
在Windows功能中启用```适用于Linux的Windows子系统```,而后在Windows CMD中直接输入```bash```,便可进入Linux环境,执行命令:
从Windows10 1709版本时开始,能够直接输入wsl
进入交互环境, bash方式会逐渐废弃掉。git
之前的 bash -c [command]
直接用 wsl [command]
来替代。github
另外一个特性是:Windows 10商店里,能够下载安装其余Linux发行版。这样就能够自由选择,不用限制到Ubuntu。
web
而后能够在程序列表中直接打开Ubuntu进入,或在CMD或Powershell中直接输入ubuntu进入:docker
PS D:\> ubuntu mush@mushroom ~ % ls go mush test mush@mushroom ~ % pwd /home/mush mush@mushroom ~ %
后面都基于wsl
,Ubuntu
,powershell
来介绍和演示。shell
Windows10自带了wslconfig
,去管理多个安装的发行版,好比卸载某个发行版,设置默认启动的发型版。ubuntu
在PowerShell中输入wslconfig /?
, 能够看到:windows
PS D:\> wslconfig /? 在 Linux Windows 子系统上执行管理操做 用法: /l, /list [/all] - 列出已注册的分发内容。 /all - 有选择地列出全部分发内容,包括目前 正安装或未安装的分发内容。 /s, /setdefault <DistributionName> - 将指定的分发内容设置为默认值。 /u, /unregister <DistributionName> - 注销分发内容。
切换默认发行版:bash
PS D:\> wslconfig /l # 适用于 Linux 的 Windows 子系统: Legacy (默认) Ubuntu PS D:\> wslconfig /s Ubuntu PS D:\> wslconfig /l # 适用于 Linux 的 Windows 子系统: Ubuntu (默认) Legacy
在Windows 1803 后,还支持更多配置。好比网络,root目录等。进入发行版后, 能够在/etc/wsl.conf
中配置。 若是没有该文件,能够手动建立一个配置:网络
[automount] enabled = true # 自动挂载 c:/ 等到 /mnt root = /windir/ options = "metadata,umask=22,fmask=11" mountFsTab = false [network] generateHosts = true generateResolvConf = true
也是从1709开始,WSL支持在Windows 10上直接使用 Linux命令:
PS D:\test> wsl ls -la total 5836 drwxrwxrwx 1 root root 4096 Jan 25 13:20 . drwxrwxrwx 1 root root 4096 Apr 20 16:25 .. -rwxrwxrwx 1 root root 105 Oct 14 2017 03-build.ps1
一样在 WSL 内也可使用Windows应用程序,好比notepad,docker:
root@mushroom:/mnt/d/go/src/code.teambition.com/soa/webhooks# docker.exe ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 63698edb01a8 quay.io/coreos/etcd:latest "/usr/local/bin/etcd" 2 days ago Up 27 hours 0.0.0.0:2379->2379/tcp, 2380/tcp etcd
这是个很是赞的特性,极大方便了开发者。但在使用过程当中发现,有个体验很是很差的地方,必须带.exe
后缀才行,否则会提示找不到命令 :
root@mushroom:/mnt/d/go/src/code.teambition.com/soa/webhooks# docker The program 'docker' is currently not installed. You can install it by typing: apt-get install docker
好比同事在mac上写了个docker build
的脚本,放到Windows上后 想使用WSL去执行,发现必须加后缀才行,这样脚本就没办法统一了
固然也能够在中装个docker,而不是使用宿主机上的docker。但这样会很冗余,并且性能很差。通过一番折腾找到几种解决方案:
在WSL 中.bashrc设置别名,去掉后缀:
alias docker=docker.exe alias docker-compose=docker-compose.exe
这样就能够正确运行命令了, 但别名只在交互环境有效,脚本执行坏境不行。
在宿主机上找到 docker.exe,而后复制一份重命名为 docker 放到同级目录,这样在wsl中也是能够执行的,有点蠢萌黑魔法的感受。
思路是定义command_not_found_handle
函数(bash 4.0+ 支持),当任何命令找不到时,都会调用调用它。 而后在该函数中尝试调用宿主机上cmd.exe,由它来来执行命令,并返回结果。
在.bashrc中添加:
command_not_found_handle() { if cmd.exe /c "(where $1 || (help $1 |findstr /V Try)) >nul 2>nul && ($* || exit 0)"; then return $? else if [ -x /usr/lib/command-not-found ]; then /usr/lib/command-not-found -- "$1" return $? elif [ -x /usr/share/command-not-found/command-not-found ]; then /usr/share/command-not-found/command-not-found -- "$1" return $? else printf "%s: command not found\n" "$1" >&2 return 127 fi fi }
或在.zshrc
中添加:
command_not_found_handler() { if cmd.exe /c "(where $1 || (help $1 |findstr /V Try)) >nul 2>nul && ($* || exit 0)"; then return $? else [[ -x /usr/lib/command-not-found ]] || return 1 /usr/lib/command-not-found --no-failure-msg -- ${1+"$1"} && : fi }
使用符号链接,讲宿主机上的docker.exe 映射到 WSL中:
ln -sf /mnt/c/Program\ Files/Docker/Docker/resources/bin/docker.exe /usr/bin/docker
差很少有2年左右,没写博客了。主要是由于从C#/Net,转向Golang相关的技术栈了,须要从新积累和学习下。前期写了段时间c++,而后写Golang,发现Golang写着舒服多了。固然跟有了女友后,变懒也有很大关系。
这篇是开头,但愿能继续坚持分享,也有利于本身成长。新博客会同步到github一份,方便备份修改。
https://docs.microsoft.com/en-us/windows/wsl/interop
https://docs.microsoft.com/en-us/windows/wsl/wsl-config
https://github.com/Microsoft/WSL/issues/2003