WSL2开启systemctl命令简单方法
上一级页面:index-wsl
前言
我们如果想要拥有一个 systemd 环境的话,该怎麽办呢?
本文记录如何提供systemd支持,目的是能够正常使用systemctl命令,并能够正常运行一些应用程序
提供完整systemd的项目有很多:
- diddledani/one-script-wsl2-systemd: The one-script variant of the systemd hack for WSL2 (github.com)
- ubuntu-wsl2-systemd-script
- wsl2-hacks
- genie
- subsystemd
- Angea
这些项目的核心原理并无大异,无非是细节处理的好坏和附加功能的多少,但最重要的一点可能是工作层次不同。
前三个脚本都工作在图中的 shell
层,要依赖外置命令执行系统调用。genie
工作在 应用程序
层,它使用 C#
编写,通过 shell
执行系统调用,比前三个还多了一层。最后两个虽然也是 应用程序
,但它们由 Rust
编写,不经 shell
,而直接由 C system call wrapper
执行系统调用,依赖最少,动态链接编译后只有几百 K。
init
我们探讨的是WSL2的发行版,而WSL2的发行版,均拥有微软提供的 init
,它是一种systemd
的替代方案,不支持systemctl
命令,
WSL2 本身是由 Windows 负责运行的,因此使用 tree 或 ps 命令时会看到根进程不是 systemd
,这将导致无法启动 Linux 系统服务的守护进程(deamon)。
当我们执行 systemctl
命令的时候,会显示出我们的 init system (PID 1)
并非 systemd
,而是微软提供的 init
。
1 | systemctl |
我们如果想要拥有一个 systemd 环境的话,该怎麽办呢?
本文记录如何提供systemd支持,目的是能够正常使用systemctl命令,并能够正常运行一些应用程序
(推荐)官方方案
官方现在已经支持systemd,见Advanced settings configuration in WSL | Microsoft Learn
(推荐)方案一–使用**wsl-distrod**
推荐这种方案,阅读官方的README,nullpo-head/wsl-distrod:Distrod是WSL 2的元发行版,它可以在一分钟内安装Ubuntu,Arch,Debian,Gentoo等系统。Distrod还具有Windows启动和端口转发功能的内置自动启动功能。 (github.com)
使当前发行版运行wsl-distrod
通过此安装,systemd 已在 WSL 2 发行版中启用。
- 下载并运行最新的安装程序脚本。
1 | curl -L -O "https://raw.githubusercontent.com/nullpo-head/wsl-distrod/main/install.sh" |
此脚本安装发行版,但尚未启用它。
- 在发行版中启用发行版
您有两种选择。如果要在 Windows 启动时自动启动发行版,请通过以下命令启用 distrod
1 | /opt/distrod/bin/distrod enable --start-on-windows-boot |
否则,如果不在 Windows 启动时自动启动发行版
1 | /opt/distrod/bin/distrod enable |
如果要在以后启用自动启动,则可以再次运行
1 | /opt/distrod/bin/distrod enable --start-on-windows-boot |
- 重新启动发行版
关闭 WSL 的终端。打开一个新的命令提示符窗口,然后运行以下命令。
1 | wsl --terminate DistroName |
例如
1 | wsl -t Ubuntu |
重新打开新的 WSL 窗口后,shell 将在 systemd 会话中运行。
另请参见
方案二–使用genie bottle
要求
**仅仅wsl2支持使用_systemd_ 或 genie **
在安装 genie 之前,最好将 systemd 默认目标设置为_多用户目标_。(multi-user.target
以命令行形式运行)
要将引导目标更改为多用户模式模式: 见如何在 systemd Linux 中将引导目标切换到文本或 GUI - nixCraft (cyberciti.biz)
1 | sudo systemctl set-default multi-user.target |
multi-user.target
是 genie 设计运行的目标,
因为许多发行版使用的默认值为 graphical.target
,这包括图形桌面的服务,
如果你的默认值为graphical.target
,在 WSL/WSLg 环境下正常运行之前,这些服务至少需要进行大量的重新配置。
安装依赖
安装 daemonize 和 fontconfig
1 | sudo apt install -y fontconfig daemonize |
你可以尝试标记它们为自动安装
1 | sudo apt-mark auto fontconfig daemonize |
过去有脚本可以替换 init 为 systemd,但现在不再推荐使用。
现在推荐使用 genie 工具,他将在用户态创建 systemd 进程
首先要安装 dotnet runtime
,因 genie 使用 .net core
下载deb文件
1 | wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb |
安装dotnet runtime
1 | sudo apt-get update; \ |
上面演示的是为 Ubuntu 20.04安装 .net core,其他linux发行版本看文档:Instll Documentations
按文档要求,添加wsl-transdebian 仓库,安装文档见:wsl-transdebian |仅限 WSL 的 apt 包的存储库。 (arkane-systems.github.io)
确保已安装lsb_release,用来获取系统信息
1 | sudo apt install lsb-release |
安装systemd-genie
下面的命令权限要求很高,用root身份执行
1 | sudo -s |
配置 wsl-transdebian 源
1 | wget -O /etc/apt/trusted.gpg.d/wsl-transdebian.gpg https://arkane-systems.github.io/wsl-transdebian/apt/wsl-transdebian.gpg |
1 | sudo apt install -y systemd-genie |
修复SSHD服务
1 | sudo ssh-keygen -A |
/etc/fstab
是用来存放文件系统的静态信息的文件。 位于/etc/
目录下,可以用命令less /etc/fstab
来查看
1 | less /etc/fstab |
需要清空/etc/fstab
1 | sudo echo '' > /etc/fstab |
回到正常用户,
1 | exit |
运行
见官方wiki:首页 ·阿卡内系统/精灵维基 (github.com)
运行命令
1 | genie -s |
一些 systemd 模块无法加载。根据首次运行输出的列表直接禁用即可
无法加载的模块列表:已知在WSL下有问题的系统单元 ·阿卡内系统/精灵维基 (github.com)
比如下面这些就已知无法加载,直接禁用即可
1 | sudo systemctl disable systemd-modules-load |
使用 reboot命令重新引导系统: 用例见Linux Reboot Command Example - nixCraft (cyberciti.biz)
1 | sudo systemctl reboot |
开机启动genie
可以用下列方案,见在每个 shell 会话中自动启动精灵 ·arkane-systems/genie Wiki (github.com):
首先进入 WSL 环境,编辑~./profile
,内容如下:
1 | # 设置genie自启动(genie 依赖于shell) |
将自动进入瓶子,除非您进入shell的三秒钟内输入n
中止,或者等待超时
然后回到 Windows,Win + R
组合键打开运行,输入 shell:startup
进入启动目录。
创建一个 vbs
文件,名称随意,内容如下:
1 | Set ws = CreateObject("Wscript.Shell") |
注:参数中的
Debian
需要改成你自己使用的 WSL 发行版名称。
更改genie的配置
genie的默认配置有一些不太方便的地方,具体来说,默认设置如下,配置文件在/etc/genie.ini
1 | [genie] |
1 | sudo vim /etc/genie.ini |
需要更改这几项
1 | [genie] |
systemd-timeout
默认的超时时间太长了,安装你系统的情况自己设置一个短一些的clone-path
复制必要的Windows环境变量到wsl-systemd-genie-bottle中update-hostname
取消在命令行中添加主机名的后缀,这能有效避免一些烦人的bug,就像如图的bug
之后,重新设置WSL主机的主机名,避免与Windows的主机名相同(不使用默认的主机名,自己生成一个WSL主机名),
genie常用命令列表
genie 的使用方法比较简单:
1 | 启动 systemd 环境 |
genie与WSLG集成
genie与vs code集成
wsl2上的systemctl 模块初始化,必做!!
有许多模块需要处理,按以下列表进行处理
如何重启系统
使用 reboot命令重新引导系统: 用例见Linux Reboot Command Example - nixCraft (cyberciti.biz)
1 | sudo systemctl reboot |
systemctl使用方法
以sshd为例,用法如下:
1 | sudo systemctl start ssh |
1 | sudo systemctl stop ssh |
在开机时启用服务
1 | sudo systemctl enable ssh.service |
在开机时禁用服务
1 | sudo systemctl disable ssh.service |
查看服务是否开机启动
1 | sudo systemctl is-enabled ssh.service |
systemctl常用命令
对于用户来说,最常用的是下面这些命令,用于启动和停止 Unit(主要是 service)。
立即启动一个服务
1 | sudo systemctl start apache.service |
立即停止一个服务
1 | 立即停止一个服务 |
重启一个服务
1 | 重启一个服务 |
显示服务的状态
1 | sudo systemctl status test.service |
在开机时启用服务
1 | sudo systemctl enable test.service |
在开机时禁用服务
1 | sudo systemctl disable test.service |
查看服务是否开机启动
1 | sudo systemctl is-enabled test.service |
查看已启动的服务列表
1 | sudo systemctl list-unit-files|grep enabled |
查看各服务的预配置(VENDOR PRESET)
1 | sudo systemctl list-unit-files |
查看启动失败的服务列表
1 | sudo systemctl --failed |
杀死一个服务的所有子进程
1 | 杀死一个服务的所有子进程 |
重新加载一个服务的配置文件
1 | 重新加载一个服务的配置文件 |
重载所有修改过的配置文件
1 | 重载所有修改过的配置文件 |
显示某个 Unit 的所有底层参数
1 | 显示某个 Unit 的所有底层参数 |
显示某个 Unit 的指定属性的值
1 | 显示某个 Unit 的指定属性的值 |
设置某个 Unit 的指定属性
1 | 设置某个 Unit 的指定属性 |
reset-failed
您可能正在寻找reset-failed
:
1 | $ Sudo systemctl reset-failed |
从systemd手册页:
reset-failed [PATTERN…]
重置指定单位的“失败”状态,或者如果没有传递单位名称,则重置所有单位的状态。当某个单元以某种方式出现故障时(即进程退出时出现非零错误代码,异常终止或超时),它将自动进入“失败”状态,并记录其退出代码和状态,以供管理员自省直至服务使用此命令重新启动或重置。
参考、引用、致谢
WSL2 的 Linux 中运行 systemctl 命令 - 知乎 (zhihu.com)
在 WSL2 上获得近乎完整的 Linux 体验 | Pan Xiao’s Blog (ddupan.top)
https://github.com/MicrosoftDocs/WSL/issues/457#issuecomment-751351142