在微软的Build 2016大会上,微软向世人介绍了其Windows Linux 子系统(测试)[WSL],这个功能允许开发者在Windows10内通过Bash运行原生的Ubunt用户模式下的二进制文件。如果你参与了Windows Insider项目,你就有机会升级到最新的Insider Builds年度更新并试用这项功能。
网页开发者通常很难选择基于什么操作系统使用什么的开发工具,WSL是由Windows内核组设计并与合作伙伴Canonical共同发布,以帮助Windows 10开发者能够继续在Windows中使用丰富的Linux开发者生态环境和一些杰出的工具,而不需要重新启动到另一个系统或虚拟机。此项功能被称为“源于开发者,服务开发者”,特别是设计于减少开发者的日常工作流程中的冲突。
在本文中,我将向你展示我发现的WSL的一些有趣的功能,指出的这些资源希望能够帮助你更好的学习它。首先,我会展示集成的基本命令比如ssh命令以便能够使用Linux服务器或设备进行工作。其次,我将演示使用 Bash 脚本非常自然的自动执行任务的能力。 再次,我会在提供的这些极好的命令行编译,相关工具以及*nix的兼容性上找点乐趣,并玩一会NetHack。最后,我会展示在 web 上使用现有 Python 和其他可用的脚本的能力。
自从我在第一台286电脑上使用Windows3.0开始,Windows就已成为我的主要操作系统和开发环境。不过,在我家中也一直放置有Linux服务器或Linux设备。在我办公室的架子上和角落里也不断添置各种Linux设备,从物联网设备(比如,树莓派和专用路由器/网关设备)到Minecraft服务器。我总要做的一件事是从我的主工作站轻松地管理和配置这些Linux计算机。
管理服务器设备
目前在我家中运行着一台无显示器的Ubuntu Minecraft服务器。这是去年我送给我10岁儿子的圣诞礼物,但结果成了我和他共同的玩具(可以说更像是我的玩具)。我过去要从我的主用Windows10电脑上使用几个客户端程序对这个服务器进行管理,但现在我只需要在Window10上使用Bash中的ssh命令行就可以了。使用PuTTY和Tera Term一类的程序当然很好,就像使用Cygwin所附带的优秀工具一样,但是我想要一种真正的本地而且自然的体验,那将很舒服。Cygwin总是让我感觉有点像在披萨店里订购炒菜。也可以,但是执行起来感觉和环境不太符合。
我在WSL中使用ssh-keygen和ssh-copy-id设置好了公共/私有密钥对,如果使用ssh,我只需输入:
$ ssh <username>@<server>
为了更快,我创建了一个别名。这是一个标准的Linux/Bash特征:
$ alias mc='ssh <user>@<server>'
现在,要访问Minecraft服务器,我只需在Windows10中的Bash提示符后输入”mc”
当然,对于任何基于Linux的Web服务器或数据库服务器或者甚至是树莓派以及类似的物联网设备,你都可以使用同样的方法作为解决方案的一部分。
在终端提示符下使用安全外壳协议(SSH:secure shell)只是出于方便和偏好。然而,一旦你习惯了直接在shell中工作,即在一个主要包括apt、node、Ruby和Python等等工具的完整环境中工作,你会开启自动化的各种可能性。
远程脚本
假设你有一大堆Linux设备或服务器,并且你想对它们执行远程命令。 如果你已经设置好了公共/私有密钥对,你就能从Bash中远程执行ssh命令。
例如,要查看远程服务器最后一次重启的时间,你可以输入:
$ ssh <user>@<server> 'last -x|grep reboot'
用安全外壳协议连接到服务器,执行last -x命令,并且搜索包含"reboot"的行。当我在我的Ubuntu Minecraft服务器上执行这条命令后,得到的结果是:
reboot system boot 4.4.0-28-generic Thu Jul 7 08:14 still running
这只是一个服务器。如果你有一个服务器列表,你也可以对它们自动执行这条命令。我在WSL中我的home目录下创建了一个servers.txt文件。其中包括一大堆Linux服务器或设备的名字-每行一个。然后,我在同一目录下创建了一个脚本,用这个脚本来读取servers.txt文件。
使用树莓派这样的设备工作多年,我养成了使用nano编辑器的习惯(在VMS中,我用LSEdit),所以在我喜欢的终端编辑器中脚本如下图所示:
你当然可以使用vim或emacs或者Ubuntu终端会话中的其它任何编辑器。
使用的语言是Bash脚本(也称为Bash shell脚本)。要执行该脚本,只需输入:
$ ./foreachserver.sh 'last -x|grep reboot'
它会遍历文件中列出的每个服务器或设备,然后通过ssh远程执行那条命令。当然,这个例子非常简单,但是你也可以扩展到本地脚本中的重定向或者其它有用的命令。Bash脚本语言足够丰富,所以你可以用它完成大多数远程管理任务。你也可以通过下载到WSL或远程计算机中的其它程序对其进行扩展。
如果你想使用本地Windows文件和资源用于和其它Linux计算机相结合的工作流程,该怎么办?或者,你根本不想使用Linux呢?Bash能够使用本地Windows文件和资源吗?或者它是一个完全独立的环境吗?
使用Windows文件
WSL可以通过/mnt/<驱动器字母>/ 目录(或挂载点)访问PC中的文件系统。例如,在WSL中可以分别使用/mnt/c/和/mnt/d/访问Windows中的C:\和D:\ 根目录。如果你想把Windows项目文件、下载文件或其它一些文件合并到基于Linux或Bash的工作流中时,这种方法特别有用。
图中的c和d映射的是我的PC上的固态硬盘和物理驱动器:
因为是逻辑挂载,所以使用shell中的mount这样的命令不会将它们像这样显示出来。但是它们完全可以满足你的需求。例如,在Windows中,我将test.txt这个文本文件存放到了C盘根目录下。在WSL中,我可以这样访问:
在Build Tour会展期间,我们需要确保所有demo在无因特网连接的情况下可以正常工作(你也不知道会展网络是什么样子)。因此为了确认在Bash/WSL demo中也可以使用Git工具,并且验证访问本地PC上的Windows文件,我在Windows系统中C:\git\NetHack建立了一个本地存储库。为了在WSL中对其进行clone,我执行下面的命令:
$ git –clone file:///mnt/c/git/NetHack
该命令行通过git使用file://协议克隆位于/mnt/c/git/NetHack目录中的存储库。你可以用类似的方式访问所有的Windows文件。
警告:和任何一个console一样,如果不小心,你都会通过Bash将Windows文件系统中的文件修改或删除掉。例如,如果你使用的是具有相应权限的Windows账号,你可以执行下面的命令,将会彻底删除Windows安装区中的文件。
$ rm -rf /mnt/c/ [不要这样做]
我之所以提出来这个问题是因为对于大多数人来说不太熟悉Linux命令,却非常熟悉Windows终端命令。
把文件系统集成在一起的秘诀是DrvFs。如果你想进一步学习文件系统以及在 WSL中是如何工作的, WSL 团队将所有细节进行了汇总,放在了 great blog post 上面(https://blogs.msdn.microsoft.com/wsl/2016/06/15/wsl-file-system-support/)。
当然,文件系统访问只是故事的一部分。许多开发任务还要涉及通过HTTP或其它网络协议访问远程资源。
建立HTTP请求
不使用编译好的程序或网页,而是使用脚本或者命令行的方式建立REST请求或其它HTTP(或FTP)请求,常常是有帮助的。就像大多数Linux发行版一样,WSL也包括了像curl和wget这样的标准工具,用以建立HTTP和其它网络请求。例如,使用curl建立到GitHub的REST请求,以获取我的配置文件信息:
$ curl -i https://api.github.com/users/Psychlist1972
HTTP/1.1 200 OK
Server: GitHub.com
Content-Type: application/json; charset=utf-8
Content-Length: 1319
Status: 200 OK
...
{
"login": "Psychlist1972",
"avatar_url": "https://avatars.githubusercontent.com/u/1421146?v=3",
"url": "https://api.github.com/users/Psychlist1972",
"name": "Pete Brown",
"company": "Microsoft",
...
}
$
你可以将这条命令和Bash脚本结合在一起来创建针对REST API的快速测试客户端,或者创建一些工具,用以对服务器上的web页进行ping测试并返回测试结果。仅仅用于下载web上的文件也很好;你只需将输出重定向到一个文件而不显示在屏幕上。
$ curl -i https://api.github.com/users/Psychlist1972 > pete.json
我也在使用PowerShell,甚至使用PowerShell中的Windows 10 MIDI编写了一些有趣的扩展(https://github.com/Psychlist1972/Windows-10-PowerShell-MIDI),而且修复了用户遇到的某些录音硬件文件损坏问题。作为一个长期的.NET开发者和爱好者,我会继续使用并扩展PowerShell,因为它对我的项目很有意义。但是在PowerShell环境中运行当今网上的那些基于Bash和Linux的开源工具和实例并不是太合适。我想使用最容易最舒服的方式来完成所有任务,有时,这也就意味着必须使用Bash来完成。
这里我仅仅介绍了有关Bash、Bash脚本和使用shell完成任务的最浅显内容。迄今为止,我一直在谈论对开发具有辅助作用的实用工具。要在WSL中进行实际开发和编译,该怎么做呢?我在Build Tour大会上对此进行了演示。
在 Build Tour 中猛击——NetHack
今年夏季早些时候,微软发言人在世界各地展示了一些Windows和微软云很酷的新开发者功能。作为其中的一部分,我们想用一个有趣的方式阐述WSL,而且在某种程度上,与开发者有关联。
我个人想使用Git和一些传统的控制台开发工具来显示。当我写Bash程序演示样本的时候,包括我(在Python和Ruby的“Hello World”)的基础知识,但希望展现一些更因循守旧的东西。
我回想起我们在Unix(DEC的Ultrix和SunOS)和VAX / VMS之间来回反弹我的大学时间。当时,UNIX几乎完全是一个以命令行的第一环境。在我的学校,大部分X用户在图形工作站的不同的窗口的少数刚开业的多个终端会话,但在后台超爽的月相墙纸。大部分学生使用VT-220端子的会话(学校被不远处的波士顿,所以我们有很多的DEC设备)。
当时,有两个大的游戏,所有的计算机科学专业的学生常玩:MUD游戏(主要是LPMUD和当时全新的DikuMUD)和NetHack。 NetHack等Roguelikes已经被认为是一些在历史上最有影响力的游戏,作为我们今天所享有的许多地牢抓取和角色扮演的游戏的前体。
NetHack有着悠久的历史和今天包含超过十年每十万的*nix的代码,以及现代增补线。游戏本身使用诅咒来作为终端互动(或其替代品),要求使用lex和yacc(或flex和bison)和CC(或GCC),以及其他开发工具创建。
NetHack主要是用C开发,同时包括一些用Bourne脚本开发的繁琐的配置工具脚本。我认为通过配置来测试WSL的兼容性以及Windows 10的Bash是一个不错而又有趣的方式,因为curses(Linux和WSL上的libncurses)的使用, 将有助于演示内置在Windows 10控制台窗口中的终端模拟器的兼容性。
以前下载NetHack源代码后,构建NetHack永远只能在时间切分的Ultrix服务器上,而如今,在我的PC上只需要几分钟就能全部完成,我享受这个(发展)过程。在Linux或者WSL上,配置、编译NetHack有简单的方式也有复杂的方式,为了节省时间,我将以简单的方式给大家介绍。
准备工作(先决条件)
首先,将系统的WSL环境更新到最新,以确保能指向软件的最新的目录(catalog),同时将基础安装包(base install)更新到最新。在安装新软件之前,这通常都是一个好的建议。
$ sudo apt update
$ sudo apt upgrade
然后,安装必要的开发工具。最简单的方式是使用build-essential工具,这里包含Linux开发人员用来编译C/C++所需的所有控制台程序。
$ sudo apt install build-essential
这个安装会花上几分钟,如果你想额外更多的操作,可以分开安装gcc、gdb、make、flex、bison及其它NetHack文档中提及到的 工具。但如果你是一个开发人员的话,同时你或许想要安装更多工具。build-essential工具包会分析需要安装什么依赖的工具包。
然后,开始安装git。 和你想的一样,也比较容易:
$ sudo apt install git
使用Linux系统的话,你可以添加一个git的PPA(Personal Package Archive,个人软件包存档)获取更多的(近期)版本,但这里一个版本就够了。
最后,我们想要在控制台中集成curses(实际上是ncurses),安装curses:
$ sudo apt install libncurses-dev
一旦完成了这些步骤,你就可以开始构建NetHack了。
编译NetHack
官方的NetHack仓库在GitHub上(https://github.com/NetHack/NetHack)。首先,我们要将NetHack抓取下来,并放在我们的home目录中的某个子目录中。
$ cd ~
$ git clone http://github.com/NetHack/NetHack
因为NetHack支持很多不同的操作系统,所以你要通过命令行做一些基本配置以告诉它我们使用的是Linux系统,并且用gcc这样的免费且开源的工具替换掉Unix上的cc。
正如我前面提及的,有很多方法可以完成这样的配置。有些考虑很周到的人将这些配置信息封装到一个hints文件中。相信我,使用hints文件和按照GitHub仓库中描述的步骤相比,会减少配置时的麻烦。在README文件或其它文档中没有非常明确地提到如何使用hints文件,我们可以这样做:
$ cd NetHack/sys/unix
$ ./setup.sh hints/linux
这会设置makefile文件以使用正确的工具、库和Linux路径。这个设置脚本功能很强大,做了大量的配置工作。令人感到高兴的是它们在WSL中同样能很好地工作。如果你对shell编程感到好奇,一定要用你喜欢的编辑器打开它一探究竟。
然后,进行最后的编译工作:
$ cd ~/NetHack
$ make all
编译完成后,还要进行安装。其实也就是将可执行文件复制到目标位置:
$ make install
这会为你创建~/nh文件夹。NetHack安装在~/nh/install/games目录中,名为nethack。要运行它,切换到那个目录(或输入完整路径)并且输入:
$ cd ~/nh/install/games
$ nethack
然后,屏幕会清屏并提示您可以开始玩NetHack了。需要注意的是在vanilla Ubuntu Linux中就可以完成编译了,不需要使用任何Windows特有的东西。
玩转 NetHack
考虑到控制台游戏的局限性,NetHack 是灵活的。说它有点神秘是有点保留的,但是我没有见到开发者回避这个很好的挑战。
它的快捷键与VI(M)相似,就是HJKL,即左,下,上和右。你可以在楼梯顶部找到"退出"来使用它们,或者按 Ctrl+C 强迫退出游戏。
在 NetHack 中,你有一个 @ 符号。每一层的房间,廊道,门 和 上下楼梯。怪物,宝物和其他物品 都由各种 ASCII 字符表示的,它没有存档,你只有一次生命。如果你在游戏中挂掉,只能重新来过,地牢是随机生成的,物品会变成隐藏模式。
为了在 NetHack 地下城生存,你要尽可能更多地收集金子和物品,尽可能杀死更多的怪物。有些目标是很难发现的,你需要玩一段时间之后才会发现他们。龙规则的武器,技巧等与地牢规则大致相似。
下面的屏幕截图是 NetHack 与三个房间和两个可见的走廊。楼梯在左上房间,我目前在右上方的房间,还有一些宝物和其他物品。
如果你的版本没有显示颜色,那就创建一个名为~/.nethackrc的文件,并添加下面的内容:
OPTIONS=color:true,dark_room:true,menucolors:true
注:如果你不喜欢ASCII字符图形,但是你又喜欢这种类型的游戏,可以在Microsoft商店中搜索“roguelike” 来找到视觉上更好看的游戏。
当然,NetHack很古老了,只有特定年龄的人才喜欢。然而,编译NetHack用到了大量重要的开发工具和*nix 操作系统的功能,以及终端模拟功能。令人高兴的是从gcc、gdb、 make、 bison和flex到更现代的git在 WSL中都能工作良好。
如果你想在Build Tour大会上看到上面的演示,可以从Build Tour加拿大大会上看到这个演讲。WSL的演示大约在6:20开始。(没错,就是Windows中的Linux子系统,不管我在那个视频中怎么说。)
我希望你能喜欢对NetHack的探险之旅!
C和C++很优秀,和所有的这些流行开发工具一样。你甚至能使用普通的Bash脚本做很多事情。但是许多开发任务还要使用Python这样的脚本语言。
Python
在互联网上可以到处找到Python的脚本实例,这意味着对许多开发者而言Python既流行又实用。当然,大多数例子假设你使用的是Linux系统。在过去,这意味着要运行这些例子的话,要么将某个Linux版本安装到另一台机器上、一个虚拟机上或者在启动时选择,要么对例子进行一些必要的修改以使用Python的Windows版本来运行它们。
无论从哪个角度来说这些问题都是完全可以克服的,但是在开发人员的日常生活中,像这样的小麻烦会积少成多。使用 WSL,你总能得到一个可以兼容Python运行的子系统和shell,而没有必要离开当前的运行环境。
在Bash shell提示符中执行下面的命令,来安装最新的Python开发版和python包安装器"pip":
$ sudo apt install python-pip python-dev
$ sudo pip install --upgrade pip
Python已经安装好了,我要告诉你如何从网上获取经典的Linux Python实例并直接使用。访问Activestate Python recipe site网站(http://code.activestate.com/recipes/langs/python/?query_start=1),选择最前面的那个Python例子。奥,我说了谎。最前面的哪个例子是打印整数名字,看来不是特别好玩,所以,我选择第二个:俄罗斯方块(Tetris)。我想你们每天都会看非常多的Python实例,所以我们一起来玩这个游戏。
打开nano,从Windows浏览器的那个页面上复制这275行Python代码,粘贴到WSL中的nano中,保存为tetris.py文件,然后执行:
$ python tetris.py
这会立即清屏,并生成一个基本的Tetris程序。正如NetHack一样,使用相同的VI标准移动键进行操作。(在还没有使用鼠标和WASD键作为移动键的时候,右手正好按在键盘上的HJKL键上。)
正如我所提及的,在Windows中不使用WSL运行Python当然可以。然而,要进行快速地工具与实例开发,在无需修改只需从已知源粘贴一些代码的情况下就能运行一个Linux Python示例,这种方式可以极大地提高开发者的工作效率。
这才是问题的关键,真的。我不是要你替换掉Python、PowerShell、C#等等这样的Windows原生工具,而是让你消除掉在现代开发工作流中快速有效地完成工作所遇到的麻烦。
在Bash、Python和所有原生Linux命令行开发工具之中,WSL完全可以满足我的Linux工作流的需要。它不是一个Linux服务器,甚至也不是一个完整的Linux客户端。它反而能完全满足我的需要,能减少
一些日常麻烦,使得在Windows中的开发甚至更有效率、更有乐趣。
重置WSL环境
你可以随意实验。如果你的WSL安装被破坏,重新安装也非常容易。但要确保将重要的东西进行备份。
C:\> lxrun.exe /uninstall /full
C:\> lxrun.exe /install
使用Bash和WSL感觉怎样?
我们希望在Windows10中使用WSL,尤其是Bash,因为这有助于大大地提高效率,消除一些日常开发任务中的麻烦。
你在Windows 10中使用WSL感觉怎样?你想如何使用呢?
WSL团队正在做大量的工作以确保其成为开发者使用的一款优秀终端工具。如果你有些反馈或遇到了一些问题,我们推荐你查看GitHub issues page(https://github.com/Microsoft/BashOnWindows/issues) 以及 UserVoice Feedback and voting site(https://wpdev.uservoice.com/forums/266908-command-prompt-console-bash-on-ubuntu-on-windo)。我们真的很想听到你的回音。