有些人将大部分工作时间都花在控制台上,有些人在必要时使用终端,并根据说明进行操作。 但是我认为每位IT专家,无论他是开发人员,系统管理员,网络工程师,还是高级Yaml开发人员,都使用命令行界面。 并非所有人都考虑改善CLI的工作环境并提高终端的生产率。 我想分享一下我的经验,即设置用于Windows的Linux的环境。

从本文中,您将了解当前在Windows 10上运行Linux应用程序所使用的工具和终端。我们将讨论
WSL 2和
Windows Terminal ,它们在需要Linux工作的用户中越来越受欢迎。 由于我的大多数用例都与通过SSH进行远程连接有关,因此大多数信息都与远程连接有关,并且具有与此相关的所有功能(通过ssh代理转发ssh密钥,转发X服务器,管理连接等)。 )
注意! 在剪切下有很多图片并且缩小了,但有时又很多,gif,如果可以适当访问Internet,建议打开文章。 如果您有兴趣在Windows下运行Linux实用程序,在CLI环境中优化工作,或者只是喜欢技术文章和彩色终端,请来关注下。 我试图通过终端的屏幕截图和屏幕快照来使文本变亮,以免感到无聊。
引言
在我的家用和便携式笔记本电脑上,我目前唯一的操作系统是Windows 10,今年我终于切换到仅使用WSL,而不是VM / dualboot / Cygwin / MinGW。 现在,我的默认终端是本地WSL Shell,可以在其中运行几乎任何任务,就像在本机Linux中一样。 此外,Intel NUC微型服务器在家庭网络上运行,在该家庭网络上,Proxmox与LXC容器和KVM一起部署,Docker在其中旋转。 我使用Windows目录中的密钥通过SSH访问所有VM。 在CLI中,使用相同的服务器和网络会花费大量时间进行专业活动。 因此,总是希望在终端中使用工具来使工作更舒适,而在Windows中总是存在问题。 但是现在一切都在改变。

本文和后续文章将重点放在正在寻找新解决方案并希望提高其外壳性能的发烧友上。 但是对于初学者来说,有些事情应该是有趣的,尽管该文章被证明非常深入地讨论了该主题,并建议读者具有Linux的一些基础知识。 所有信息都是根据使用WSL(终端)的个人经验收集的,以及在不断改进配置和查找方便的工作工具的过程中无休无止地翻页Stack Overflow和Github问题。
Windows Linux子系统(WSL)2
在Internet和Habr上有几篇关于WSL的常规文章(
曾经有一篇关于使用X服务器安装/配置WSL的文章,关于WSL 2的两篇文章,关于在VSCode中使用WSL开发Python的
三篇文章)描述了系统的安装和配置。 但是,并非所有安装操作都已经相关,而且陷阱的限制越来越少。 我不会详细介绍安装过程,有关安装WSL当前(第二个)版本的
说明在Microsoft网站上 ,您也可以在Internet上找到简短的
教程 。

现在WSL仍在积极开发中,最近(
2019年6月 )发布了新版本的WSL 2,该版本仅适用于Windows Insiders成员的Windows新版本。 如果可能的话,我建议您立即将WSL升级到版本2,因为它改进了系统调用的工作,与网络,FS一起使用,并且通常它是基于不同的体系结构构建的,并且根据一些报告,与第一个版本相比
,速度提高了
20倍 。
您可以在
开始->设置->系统->关于中看到Windows 10和OS构建的版本,要安装WSL 2,您需要
Windows 1903和至少构建版本
18917 。 如果您不是
Windows Insider计划的成员,则最有可能的更新要等到一个稳定的版本才能发布。 因此,如果要升级到最新版本,则可以在
开始->设置->更新和安全-> Windows Insider程序中启用早期访问(
快速 ),更新并禁用进一步的更新。 值得考虑的是,尚未安装经过大规模测试的更新,这可能会影响稳定性。
应当记住,在构建版本
18995之前
, WSL在处理已安装的Windows磁盘上的文件时存在一个
错误 ,表示为输入/输出错误,仅重新启动WSL(PowerShell中的
wsl --shutdown )有帮助。 通常,WSL版本1(默认设置)和Windows的非预览版发行版中仍然存在许多固定的错误。 如果您的操作系统更新受公司政策管制,则很可能最新的更新将无法到达,因此您需要牢记这一点。 在其中一台笔记本电脑上,我拥有的版本为18956,并且没有更新,尽管在“内部程序”设置中选择了“
快速”选项。 几个月前,一个干净的系统已安装在另一台笔记本电脑上,并且更新会定期到达并安装。
安装WSL 2
WSL要求启用Hyper-V,因为Linux发行版使用Hyper-V虚拟化在轻量级VM上运行。

接下来,我将以
Kali Linux为例提供WSL的CLI PowerShell发行版的简要安装说明。 如果您喜欢
Ubuntu或
其他可用的
Linux发行版,请用适当的链接和名称替换链接和名称。
检查Windows Build版本:
Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion" | Select CurrentBuild
激活
VirtualMachinePlatform和
Microsoft-Windows-Subsystem-Linux组件
:Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform
重新开机
接下来,从Microsoft Store(
https://aka.ms/wslstore )安装发行版,或继续在PowerShell中运行:
curl.exe -L -o kali.appx https://aka.ms/wsl-kali-linux-new
Add-AppxPackage .\kali.appx
rm .\kali.appx
启动WSL控制台(发行版应出现在“开始”菜单中,按发行版的名称进行搜索),等待邀请安装新用户,然后关闭控制台。
现在,如果在PowerShell中执行,则分发应该出现在列表中:
wsl -l -v
如有必要,将发行版本转换为WSL版本2格式:
wsl --set-version kali-linux 2
wsl --set-default-version 2
将root设为默认用户(可选):
kali config --default-user root
如果收到错误消息
“连接尝试失败,因为连接的一方在一段时间后未正确响应,或者连接建立失败,因为连接的主机未能响应。” ,那么您将拥有一个下一个版本的构建(已修复)在最新版本中)的错误。 像往常一样,有一种
解决方法 ,或者使用Ubuntu发行版,在没有最新版本的构建上,我没有任何问题。
如有必要,您可以根据
说明将WSL虚拟磁盘移动到另一个分区(与C:不同)。 最好立即执行此操作,因为并非所有操作都能顺利进行。
关于安全的免责声明 。 在WSL和家庭网络中的其他Linux服务器上,我没有运行任何关键系统,并且网络上没有其他用户(我除外),因此我几乎遍地都是root用户,并通过密钥进行ssh身份验证。 我知道这不是最佳做法,但我在谈论的是个人开发环境,我看不出创建非root用户的意义。 本文不会考虑安全性问题,有一天我会写它(关于如何通过TLS与家庭网络中的集中式证书更新来组织服务交互;关于服务器之间的同步
〜/ .ssh / config ,转发,端口和键等)。
WSL配置
从版本
17093开始,主要的WSL配置文件位于分发系统FS上的
/etc/wsl.conf中 ,它描述了每次引导分发时将应用的设置:
- 自动挂载-自动挂载Windows驱动器
- 网络-生成resolv.conf文件,主机
- 互操作-启动Windows进程并将Windows $ PATH添加到Linux $ PATH
最初,WSL没有此配置,必须手动注册:
[automount]
enabled = true
root = /mnt
options = "metadata,umask=22,fmask=11"
mountFsTab = true
[network]
generateHosts = true
generateResolvConf = true
[interop]
enabled = true
appendWindowsPath = true
某些设置与默认值一起
使用 ,而
/etc/wsl.conf为空,但是要对文件进行正确的操作,您至少需要注册
options参数,否则Windows文件将具有777权限,并且不能从Linux更改。

您可以使用以下命令从PowerShell重新启动发行版:
wsl -t kali-linux
之后,您可以更新软件包并自己调整操作系统。 我不会涉及Linux的shell设置和环境,我将在下一篇文章中讨论。
apt -y update && apt -y upgrade
WSL 2文件系统和性能
WSL版本2内的文件存储在VHDX虚拟磁盘上,ext4用作文件系统。 您可以通过以下格式的路径访问rootfs WSL:
\\wsl$\{DistroName}\
或者,您可以键入
“ explorer.exe”。在CLI中,Windows浏览器将在当前目录中打开。
WSL版本1不使用VHDX,可以轻松访问Linux文件所在的目录,Microsoft
强烈建议不要从Windows更改Linux文件。 在新版本的WSL中,使用
Plan 9 Filesystem Protocol文件服务器提供对虚拟磁盘上FS的访问。

在WSL的早期版本中,存在文件系统性能问题,因为通过Windows API模拟了系统调用,文件访问缓慢且不稳定。 在2019年底,WSL 2更改了其架构并使用了本机Linux内核。 从youtube
幻灯片上的幻灯片来看,
Linux体系结构的新Windows子系统:深入研究 ,磁盘操作的性能提高了2-5倍。
最大磁盘容量限制为256GB,如果超出该容量,则需要调整大小,说明在
文档中 。
WSL最初在使用RAM后释放资源时遇到问题。 Build 19013解决了此问题。 如果运行苛刻的任务(例如,组装rust应用程序),您会注意到
Vmmem进程将位于任务管理器的顶部,但是在最新版本的WSL中,内存消耗已大大减少。

联播网
Linux中的主机名(主机名)取自Windows中的PC名称,而不管
/ etc / hostname中写的是什么,或使用
hostnamectl set-hostname命令写入。
与第一个版本不同,在WSL 2中,网络通过虚拟Hyper-V交换机工作:
❯❯ ipconfig.exe | grep IPv4
IPv4 Address. . . . . . . . . . . : 192.168.88.200
IPv4 Address. . . . . . . . . . . : 172.31.160.1
IPv4 Address. . . . . . . . . . . : 172.27.144.1
❯❯ ip -br -4 ad show dev eth0
eth0 UP 172.27.150.196/20
❯❯ ip ro list default
default via 172.27.144.1 dev eth0

在这种情况下,网络
172.27.144.0/20在WSL下使用,其第一个地址(
172.27.144.1 )是Windows主机系统。
从Linux,您可以通过网络访问主机服务(在Windows上运行),例如:
❯❯ nmap -p 3389 $(cat /etc/resolv.conf | grep nameserver | awk '{print $2}')
Windows IP地址来自
/etc/resolv.conf ,根据
wsl.conf设置自动生成。
相反,如果需要从Windows应用程序连接到Linux套接字,则必须访问WSL的IP地址。 有一个警告-在Linux中,该服务不能在
localhost(127.0.0.1)上运行,而必须在地址
0.0.0.0上运行 。 例如,要将SOCKS5代理快速提升到您的VPS,您需要使用
动态端口转发参数启动SSH:
❯❯ ssh -D 0.0.0.0:2299 -N -f proxy.example.com
此后,在Windows应用程序(例如Chrome)中,作为SOCKS5地址,而不是
localhost ,而是注册WSL地址,在这种情况下为
172.27.150.196 。 顺便说一下,以这种简单的方式通过Chrome中的VPS隧道传输流量,就可以通过IPv6使用对站点的访问。

Linux每次重新引导后都会更改其IP地址,因此在需要端口转发持续工作并自动启动的情况下,您需要寻找解决方法。 解决拐杖问题的方法有很多,拐杖的程度各不相同,您可以在github上阅读有关此
问题的更多信息。 我使用了
go-wsl2-host实用程序,该实用程序实现Windows服务,该服务会自动将WSL IP地址添加到Windows
主机文件中 ,因此您可以在主机系统上注册主机名(例如
ubuntu.wsl)并访问其上的Linux。 但是,所有这些问题并不能很好地解决,仍然需要等待Microsoft解决这些问题。
UPD 在撰写本文时,我发现有一些更新(内部版本
18945 ),使通过
本地主机的服务访问在WSL中运行的服务成为可能。 没错,事实证明,由于存在一个
错误,导致每个人仍然无法使用该
错误 ,八月构建的
修补程序为
18970 。 由于并非所有人都收到更新,即使我是Windows Insiders计划的成员,我也没有调整信息,也许它会帮助某人建立网络交互。
Windows上的OpenSSH和自动启动服务
Windows 10与Windows Server 2019一样,都带有
OpenSSH fork ,它包含所有熟悉的ssh-keygen,ssh-add,scp和其他实用程序,包括ssh-agent和sshd服务器本身。 可以通过“
应用程序”>“应用程序和功能”>“管理可选功能”来
安装客户端和服务器
,但是ssh客户端版本不是最新的。 我遇到了一个错误,该错误不允许
我使用
ProxyJump选项通过跳转主机
连接到主机,事实证明此问题已解决,但我必须手动更新客户端SSH。 您可以通过从github上的
Releases部分下载zip并解压缩来安装Win32 OpenSSH的当前版本,例如,在
C:\ Program Files \ OpenSSH中 。 从
$ PATH (
%SYSTEMROOT%\ System32 \ OpenSSH \ )调用第三方软件ssh.exe(例如,在VSCode中使用远程开发模式时),您需要更改环境变量。 通过GUI的“
开始”>“编辑系统环境变量” (“
开始”>“更改系统环境变量” )可以
更改环境变量 ,在那里您需要在旧版本之上放一个新方法。
由于Systemd在WSL中不起作用,因此在系统启动时启动服务就存在问题。 有几种方法可以在WSL中配置ssh服务器自动启动,最简单的方法是在“任务计划程序”中创建任务,您可以在其中指定服务器启动命令。 在Internet上,可以通过脚本
vbs ,
ps1或
bat找到不同的启动
说明 。 几乎所有方法的问题在于,触发器是启动主Windows操作系统,也就是说,如果WSL崩溃并且您必须重新启动系统(
wsl -t ),那么Linux将在不运行服务的情况下启动。 Windows启动时,WSL分发仅在首次访问时启动。
我在WSL内的便携式计算机上使用SSH服务器,以便可以从一台计算机远程访问另一台计算机。 而且,由于我使用ssh端口转发技术和经过深思熟虑的SSH客户端集中配置,因此我可以透明地转到所有服务器,输入主机名而不是地址。 也就是说,即使将其中一台笔记本电脑连接到移动网络,autossh守护程序也将连接到跳转主机,而我仍然可以转到计算机,没有NAT会成为障碍。 因此,对我来说sshd总是启动很重要。

在WSL中访问SSH的唯一可行方法是转发SSH端口。 这可以通过WSL本身使用
RemoteForward来完成,也可以通过家庭网络中的另一台服务器来完成。 很少有人需要它,而这已经是高级了,所以我只给出一个有效的命令:
❯❯ ssh -R '*:2363:*:22' -N -f mt.example.com
现在,当连接到地址
mt.example.com:2263时,您可以直接进入WSL。
如果计划在WSL中提升SSH服务器,则必须记住在
/ etc / ssh / sshd_config中配置必要的服务器启动参数。 为了避免与端口22上的服务绑定冲突,如果已安装Windows中的OpenSSH服务器,则应将其禁用或完全删除(“
应用程序”>“应用程序和功能”>“管理可选功能” )。
X转发
事实证明,在Windows 10中有一个
clip.exe实用程序,使您可以将stdout直接重定向到Windows剪贴板,这是一个令人愉快的时刻。 这在tmux等程序中使用非常方便,而且由于转发了X服务器,因此还可以从远程主机复制文本。 为了使一切正常运行,必须始终在Windows上运行X服务器,并正确设置
$ DISPLAY变量。
有点无聊的理论。 在运行X的* nix系统上,存在不同类型的剪贴板(
主要,辅助,剪贴板 ),在本文的上下文中,它不是那么重要,但是对于总体了解工作机制很重要。 在Linux上,有两个实用程序(xclip和xsel)可用于剪贴板。 这两个实用程序具有相似的功能,但在xsel中稍大一些,但转发缓冲区内容所需的基本功能是相同的。 在X应用程序中,选定的文本属于主要选择,并通过鼠标中键插入,在xclip和xsel中,缺省情况下使用主要选择。
例如,要将变量的内容复制到默认缓冲区,您需要将stdout传递给xclip实用程序的stdin,而无需其他参数:
❯❯ echo -n $DISPLAY | xclip
要显示默认缓冲区的内容,请使用
-o开关运行xclip:
❯❯ xclip -o
172.20.160.1:0
为了使剪贴板通过X服务器重定向并在本地X服务器上运行图形应用程序,您需要在
$ DISPLAY变量中设置IP地址,该地址是WSL的默认网关。 到目前为止,还没有什么比从
resolv.conf (Windows自动生成)中获取更好的了。 因此,最简单的方法是在外壳配置文件中注册
$ DISPLAY变量的导出(例如,对于zsh,
〜/ .zshrc )。
❯❯ echo "export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}'):0" >> ~/.zshrc

作为X服务器,我选择了免费的
VcXsrv ,它可以与缓冲区一起使用,具有不同的窗口显示模式,并使用指定的选项从命令行启动。
使用链接到要点,您可以看到所有选项。
您可以像这样在Task Scheduler中为X服务器创建自动运行任务:
Triggers: At startup
Actions: Start a program
____Program: "%ProgramFiles%\VcXsrv\vcxsrv.exe"
____Arguments: -wgl -dpi auto -ac -multiwindow
SSH键
为了使Windows中的程序可以使用SSH密钥(例如,在使用远程GitHub存储库时使用编辑器),并且在WSL中没有密钥的第二个副本,最好在Windows
%HOMEPATH%/. ssh中生成密钥,并在主目录中创建符号链接WSL目录。
ssh-keygen -f /mnt/c/Users/${WIN_USER}/.ssh/id_rsa -b 4096
ln -sf /mnt/c/Users/${WIN_USER}/.ssh/id_rsa ${HOME}/.ssh/id_rsa
ln -sf /mnt/c/Users/${WIN_USER}/.ssh/id_rsa.pub ${HOME}/.ssh/id_rsa.pub
或者,在
〜/ .ssh / config中,您可以通过指定Windows磁盘上键的路径来指定
IdentityFile参数:
Host *
IdentityFile /mnt/c/Users/${WIN_USER}/.ssh/id_rsa
如果密钥是从某处复制的,并且文件权限设置不正确,请正确设置权限:
chmod 600 /mnt/c/Users/${WIN_USER}/.ssh/id_rsa
chmod 644 /mnt/c/Users/${WIN_USER}/.ssh/id_rsa.pub
chmod 700 /mnt/c/Users/${WIN_USER}/.ssh

因此,当进一步
使用SSH密钥设置
访问权限时,无论使用Windows和Linux应用程序,都只能通过一个位置的一组密钥来唯一标识用户。 现在,您可以将公钥添加到服务器/服务中,您需要从该计算机/服务中删除。 如果家庭网络上还有其他设备需要SSH访问,则将公钥复制到这些服务器(
ssh-copy-id )是正确的,但是您无需将一台服务器的密钥复制到另一台服务器。 由于在通过SSH进行工作时有可能(并且有必要)使用ssh-agent,因此当从一台服务器连接到另一台服务器时,该代理会注意对转发密钥进行授权。 为了使所有功能正常运行并按预期进行,您需要注意
〜/ .ssh / config文件
,在该文件中,您需要注册所有必需的选项。
Host *
TCPKeepAlive yes
ServerAliveInterval 30
ServerAliveCountMax 3
ForwardAgent yes
AddKeysToAgent yes
ForwardX11 yes
ForwardX11Trusted yes
选择在Windows上的Linux中工作的终端
首先,我想对可以运行WSL的Windows的现有终端外壳进行小幅回顾。 在用户中,功能
强大的MobaXterm处理器很
流行 ,它可以创建各种会话,包括图形会话(WSL,bash / zsh,Mosh,RDP,VNC等),允许您创建宏并运行脚本,具有许多设置和功能, ssh代理,可自动运行ssh端口转发,甚至具有内置的ftp / tftp / http服务器,但该产品是封闭源,而且需要付费。
Hyper是另一个更现代的终端模拟器,它允许您运行WSL Shell,该终端基于HTML / JS / CSS构建,并使用node.js模块形式的插件进行扩展(
真棒列表 )。 还有其他终端允许您使用不同程度的拐杖(
ConEmu ,它的fork
Cmder ,
WSLtty等)运行WSL,但是我将不加理会它们。

在本文的进一步内容中,我们将讨论我最近切换到的
Windows Terminal ,到目前为止,我只是在经历积极的情绪。
Terminal仍处于beta版本,但运行稳定。 当前实现的多选项卡功能,面板分离(拆分),终端连接的自定义配置文件,配色方案等,仅此而已。 但是这个功能已经足够了,我什至喜欢软件不会因多余而过载—就像开发人员遵守
KISS原则一样。
终端从Windows控制台(ConPTY)项目演变而来,学习了如何支持ANSI / VT序列,24位RGB真彩色和UTF-8。 跟随Habré上的链接(
开始 ,
继续 ),对一系列
Windows Command-Line博客文章进行了精彩的翻译
:Windows Console内 ,介绍了终端创建的历史,传输转义序列的相关标准,代码页,unicode,终端仿真器的出现以及未来的发展。已经是Windows命令行的演变。 技术人员可能会感兴趣。 从事此开源项目的工程团队维护
Windows命令行 devlog,该日志不仅完全用于WSL和Windows Terminal。 在那一刻之前,我从未相信我会感兴趣地关注MS产品的开发,但是它们作为WSL,Terminal和VSCode开发的一部分所做的工作确实值得尊重。
Microsoft Open Source Stories (在Habré上有
翻译 )中描述了WSL的开发是如何开始的。 顺便说一下,微软自2016年以来一直是
Linux基金会的白金会员。
安装和配置Windows Terminal
您可以从
Windows应用商店中安装Windows Terminal,也可以从项目github上的“
发行”部分下载二进制文件,所有相关信息,说明和常见问题解答也都在其中。 该终端至少需要Windows 1903和内部版本
18362 。 最好通过Windows应用商店进行安装,因为在这种情况下,直接从应用商店进行更新比较容易。 定期发布更新;该终端
的第一个版本的
路线图已在github上列出。 目前,已经实现了版本1的所有功能(根据计划,要在2019年底之前实现所有改进),然后需要进行几个月的修复错误工作,并计划在2020年4月正式发布Terminal v1.0。 很高兴,MS现在位于github上,他们的软件已经学会显示日志,可理解的错误,并且可以轻松地搜索任何问题。

终端中的设置还不多,但足以满足舒适的工作需求,该产品正在积极开发中,
github上的用户可以创建功能请求或错误报告。 开发人员参与与用户讨论问题,经常在发现错误时提供解决方法。

该配置以json格式存储,保存后立即应用。 如果仅因为您可以应用良好的做法来管理工作环境的配置,那么这很方便-我将所有Linux配置存储在git存储库中,在Windows上我仅使用工作工具中的VSCode,可以通过github gist同步配置,并将本地工作区配置分别保存在dotfiles中。 因此,终端使用与VSCode相同的热键和配置格式沿相同方向移动。 顺便说一句,通过VSCode编辑配置很方便,特别是如果您已经使用过MS的出色编辑器。 终端配置文件已经包含许多默认设置,并且正确的编辑器使您可以查看所有选项以及
模式中的
键和
值选项的说明(当项目尚无完整文档时,这特别方便)。 另外,所有IDE芯片都可以自动完成,智能感知,语法检查,格式设置等形式提供。
此处提供了开发人员文档,但是现在
这里只是一小页用户文档。 单独的
页面专用于json配置文件中写入的设置。 从那里您可以发现设置在结构上分为:
- 全局(默认配置文件,终端窗口的初始大小,主题等)
- 按键绑定
- 配置文件(特定于每个终端的设置)
- 方案(配色方案)
有一个动态配置文件,它们会自动出现在配置中并具有
source属性。 WSL Azure Cloud Shell. WSL (, Ubuntu),
GUID ,
source ,
commandline wsl -d {DistroName} .
- , . :
Fira Code , . , CLI , , .

Windows . github releases .
(
fontFace )
Character Map (
). ,
Start -> Settings -> Personalization -> Fonts , , , .

结论
, , Windows Terminal WSL. ZSH tmux, VM dotfiles . , / / .
Docker WSL 2 , , .
, , - . - , , . - , , .
References