WSL2因为是基于Hyper-V虚拟化的一个Linux,因此我想着在WSL里跑Docker。当我高高兴兴地安装好了Docker之后发现不能启动,因为PID为1的进程不是systemd,而是init,让我这个菜鸡呆了。一番搜索之后发现有人在GitHub给出一个解决方案,Genie,原理是利用Linux namespace实现隔离,在隔离出的空间里运行systemd,这样systemd的PID就是1了。
看过代码之后得到里几个关键的命令
我们的步骤是
- 用
pidof
检查是否有systemd
进程,有则跳到3,否则2。 - 让
unshare
运行systemd
,这样systemd
在新的namespace里的PID就是1。整个命令用daemonize
命令执行,这样创建出来的systemd
以后台进程形式一直运行。 - 用
nsenter
和runuser
进入新创建的namespace里以某个用户身份运行shell。
于是我们可以得到这样的一个脚本,GitHub传送门
#!/bin/bash
systemd_pid=
if [ -z $(pidof systemd) ]; then
daemonize /usr/bin/unshare -fp --propagation shared --mount-proc systemd
fi
while [ -z $systemd_pid ]
do
for pid in $(pidof systemd)
do
systemd_pid=$pid
done
done
if [ -z $WHO ]; then
WHO=root
WD=/
else
WD=/home/$WHO
fi
nsenter -t $systemd_pid -m -p --wd=$WD runuser -m -p -u $WHO zsh
使用方法:
WHO=`whoami` sudo -E ./wslsystemd.sh
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。