文章目录
- 背景
- 相关知识
- systemd
- init
- 安装
- 方法一:微软官方支持方法(推荐)
- 方法二:安装daemonize实现
- 参考
背景
微软官方推出Windows Terminal第一时间,我就安装了这个终端软件。现在GitHub已经有86.8k星,且发布了86个版本。我会将它与WSL以及Linux发行版结合使用,在Windows系统下搭建Linux开发环境。很多Linux发行版都是使用systemd
来管理程序进程,但是在WSL中默认是用init
来管理进程的,所以为了符合自己的使用习惯,且省去不必要的学习成本,就在WSL的发行版(我这里安装的是Ubuntu22.04)中支持systemd
,也就可以使用systemctl
命令来启停进程。
相关知识
能够支持使用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。
systemd
在较新的Linux系统上,都使用systemd
管理进程,成为系统的第一个进程(PID 等于 1),其他进程都是它的子进程。systemd为系统启动和管理提供了完整的解决方案。它提供了一组命令。字母d是守护进程(daemon)的缩写。
init
WSL2 的发行版均拥有微软提供的 init
,它是一种 systemd
的替代方案,不支持 systemctl
命令,
WSL2 本身是由 Windows 负责运行的,因此使用 tree
或 ps
命令时会看到根进程不是 systemd
,这将导致无法启动 Linux 系统服务的守护进程 (deamon)。
当我们执行 systemctl
命令的时候,会显示出我们的 init system (PID 1)
并非 systemd
,而是微软提供的 init
。
systemctl
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down
ps u -q 1
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 908 592 ? Sl 10:31 0:00 /init
安装
首先,需要确认你使用的是WSL2版本,可以在PowerShell中执行如下命令查看:
wsl -l -v
如果默认版本是1,可以使用如下命令进行配置,其中<Version>
修改成2
即可:
wsl --set-default-version <Version>
还可以使用如下方式设置默认的Linux发行版,其中<distro name>
替换为要配置的Linux发行版名称。例如,wsl --set-version Ubuntu-20.04 2
会将Ubuntu20.04发行版设置为使用WSL2:
wsl --ser-version <distro name> 2
方法一:微软官方支持方法(推荐)
在网上找到很多种支持的方法,最简单的就是微软官方提供的方法,仅需要添加一个配置文件即可。
-
在Windows Terminal中打开Ubuntu22.04
-
在
/etc
目录新建wsl.conf
文件,添加如下内容:[boot] systemd=true
-
关闭当前Ubuntu窗口
-
打开PowerShell命令行,重启WSL实例
wsl --shutdown
-
重新在Windows Terminal中打开Ubuntu发行版,输入如下命令检查是否成功:
systemctl list-unit-files --type=service
方法二:安装daemonize实现
在官方支持systemd
之前,我是使用这个方法来实现的。
-
安装
daemonize
和fontconfig
sudo apt install -y fontconfig daemonize
-
修改
/etc/profile
,末尾添加如下配置SYSTEMD_PID=$(ps -ef | grep '/lib/systemd/systemd --system-unit=basic.target$' | grep -v unshare | awk '{print $2}') if [ -z "$SYSTEMD_PID" ]; then sudo /usr/bin/daemonize /usr/bin/unshare --fork --pid --mount-proc /lib/systemd/systemd --system-unit=basic.target SYSTEMD_PID=$(ps -ef | grep '/lib/systemd/systemd --system-unit=basic.target$' | grep -v unshare | awk '{print $2}') fi if [ -n "$SYSTEMD_PID" ] && [ "$SYSTEMD_PID" != "1" ]; then exec sudo /usr/bin/nsenter -t $SYSTEMD_PID -a su - $LOGNAME fi
-
在文件
/etc/sudoers
末尾添加如下内容%sudo ALL=(ALL) NOPASSWD: /usr/sbin/daemonize /usr/bin/unshare --fork --pid --mount-proc /lib/systemd/systemd --system-unit=basic.target %sudo ALL=(ALL) NOPASSWD: /usr/bin/nsenter -t [0-9]* -a su - [a-zA-Z0-9]*
-
重新加载/etc/profile使新配置生效
source /etc/profile
参考
-
Systemd support is now available in WSL!
-
使用 WSL 在 Windows 上安装 Linux
-
WSL2开启systemctl命令
-
WSL2 开启 systemctl 命令简单方法