Mac 和 Windows 哪个更好,估计还能再吵几年。抛开部分硬件上的差距,Windows 用作开发上确实有点不顺手,毕竟大部分后端程序都是运行在 Linux 服务器上,macOS 占有先天优势。之前都是通过在 Windows 上起虚拟机来解决这个问题,如今 Windows 10 推出的 WSL(Windows Subsystem for Linux),成为了新的选择。
WSL 的官方介绍:
The Windows Subsystem for Linux lets developers run GNU/Linux environment - including most command-line tools, utilities, and applications - directly on Windows, unmodified, without the overhead of a virtual machine
简单来说就是不需要修改,无需虚拟机,就可以在 Windows 上直接使用 Linux 环境(grep
, sed
, awkd
等),运行 Linux 程序(vim
, MySQL
, Apache
等)。这就很舒服了,小孩子才做选择,大人全都要,实际如何我们来实践一番。
目录
安装
首先是按照,非常简单,开启子系统功能后在应用商场选择一个发行版的 Linux 安装就行。官方指南:https://learn.microsoft.com/en-us/windows/wsl/install
启动之后就可以使用了,你可以根据自己使用习惯,做一些初始化的设置(oh-my-zsh啥的)这里就不细说了。WSL 默认是通过安装的应用进入的(直接运行 bash.exe 也行),但大家还是喜欢通过 Xshell 等工具进入了,这就需要做一些配置。WSL 和 Windows 本机是端口共用的(这点特别注意,防止程序端口冲突了),直接通过 127.0.0.1 就能连接上,剩下的就和直接使用 Linux 差不多了。
但是,等你重启电脑,再使用 Xshell 连接时发现连不上了,没有 sshd 进程了,每次都需要打开 WSL 程序然后再运行 sudo service ssh start 有点麻烦。这就是 WSL 不一样的地方了,WSL 不是真正的一个系统,没有开机
启动这一说,把 sshd 设置成开机启动也没有用。既然不能加入到 WSL 的启动项,那就加入到 Windows 的启动项中:
编写 run_wsl.vbs
脚本,用来在 bash.exe 中启动 sshd,然后将脚本放到系统启动目录里面(WIN+R 运行 shell:Common Startup 或者 shell:startup)就行了。
1 2 | set ws=wscript.createobject("wscript.shell") ws.run "C:\Windows\System32\bash.exe -c 'sudo /usr/sbin/service ssh restart'",0 |
不过需要注意 sudo 需要输入密码,还得把密码关了。WSL 中运行 sudo visudo 增加一行:ubuntu ALL=(root) NOPASSWD: ALL,表示 ubuntu (换成自己的)这个用户使用 sudo 运行任何命令时都不用输入密码。
当然安装之后可能会遇到一些其它问题,主要是一些安全软件和 WSL 不兼容,比如卡巴斯基会让 WSL 无法联网,腾讯的 TGP 会影响绑定端口,遇到了只能暂时关掉相关软件,相信之后这些问题会越来越少。
使用 Redis
之前在 Windows 上使用 Redis 比较麻烦,有一个 Windows 版的 Redis 但已经很久没有更新了,还有就是选择虚拟机。现在直接在 WSL 里面编译安装(make & make install)就行了。写好配置文件,sudo redis-server /etc/redis/redis.conf 运行即可。
不过有些同学可能会像我之前把 Redis 注册为 systemd 服务,但发现会报错:System has not been booted with systemd as init system (PID 1). Can't operate 说的也比较明白,系统不是通过 systemd 启动的。其实 WSL 不是一个真正的系统,应该说是一个容器,类似 Docker(这么一说感觉微软野心好大)。
(图片来源:https://learn.microsoft.com/zh-cn/archive/blogs/wsl/windows-subsystem-for-linux-overview)
在 WSL 中运行的程序是真正的 Linux 二进制文件,不是移植版,不过当程序由用户态切换到内核态时lxss.sys
和lxcore.sys
驱动将会将 Linux 的系统调用翻译为 NT APIs 来模拟 Linux 内核。简单来说 WSL 是将 LInux 底层 API 用 NT 实现了一遍(所以 WSL 中没有 Linux kernel 代码),而且有些操作还是 Linux 独有的,比如fork()
,可想而知这里面工作量有多大,任重而道远。
言归正传,Redis 已经在 WSL 中启动了,我们试试在 Windows 上能不能连上:
完美,就和 Windows 本地装的 Redis 一样。
与IDE集成
虽然说大部分语言都是跨平台的,但是还是有很多差别,比如 Python 的 epoll 只能在 Linux 下使用。在 Windows 上开发不是很方便,没有智能提示,还需要上传到服务器运行、调试。有了 WSL,现在可以在 Windows 上开发,然后直接在 WSL 里面运行。
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 | #!/usr/bin/env python3 # -*- coding: utf-8 -*- import socket import select # 创建套接字 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(('127.0.0.1', 6688)) s.listen(100) # 创建一个epoll对象 epoll = select.epoll() epoll.register(s.fileno()) clients = {} while True: events = epoll.poll() for fd, events in events: if fd == s.fileno(): conn, addr = s.accept() clients[conn.fileno()] = { 'conn': conn, 'addr': addr } print("new client {}".format(addr)) epoll.register(conn.fileno(), select.EPOLLIN | select.EPOLLET) elif events == select.EPOLLIN: # Available for read recv = clients[fd]['conn'].recv(1024) if recv: print("recv {} from {}".format(recv.strip(), clients[fd]['addr'])) clients[fd]['conn'].sendall(b'echo ' + recv) else: # 客户端断开 print("close client {}".format(clients[fd]['addr'])) del clients[fd] epoll.unregister(fd) else: print(fd, events) |
WSL 中运行,并通过 Windows cmd 连接:
当然这也是不太方便,两个程序切来切去,更近一步,让这些都在 IDE 中进行。 首先要让当前代码在 WSL 中运行,新建一个 WSL Interpreter(获得运行环境和智能提示),填写需要的 Python 路径。再把 Terminal 的环境也改成 bash.exe。
最后点击 IDE Run 按钮,然后打开 Terminal,运行 telnet 连接上去做测试,这一切都在 IDE 里面,沉浸式工作体验,效率提升大幅提升,完全感受不出来是在使用 Windows。
结语
其实吧,你看宇宙第一 IDE:Visual Studio 都有 Mac 版了,平台间的差距都被各种软件抹平了。少点撕逼,多提高工作效率,少加班才是正道。
参考资料
在wsl下安装使用sshd全攻略
Win10 的 Linux 子系统是怎么实现的,https://www.bilibili.com/video/av15400416/
https://learn.microsoft.com/en-us/archive/blogs/wsl/
https://www.jetbrains.com/help/pycharm/using-wsl-as-a-remote-interpreter.html