WSL(Windows Subsystem for Linux / 适用于Linux的Windows子系统)中使用systemctl命令会报以下错误:

System has not been booted with systemd as init system (PID 1). Can’t operate.
Failed to connect to bus: Host is down

那出现以上的问题应该怎么解决呢?

微软声明

在官方文档的数据库入门里面有提到这一点:

其他教程可能会使用操作系统的内置 init 系统来启动 MongoDB。 你可能会看到在教程或文章中使用了命令 sudo systemctl status mongodb。 目前 WSL 不支持 systemd(Linux 中的服务管理系统)。
你应该不会注意到有什么区别,但是如果教程建议使用 sudo systemctl,请改用 sudo /etc/init.d/。 例如,对于WSL,sudo systemctl status docker 应改用 sudo /etc/init.d/docker status,或者也可以使用 sudo service docker status

解决方法

使用其他命令

正如微软声明所说,以docker为例,sudo systemctl status docker 改用 sudo /etc/init.d/docker status,或者使用 sudo service docker status

* 虽然不符合大多数人的习惯,但这个方法确实可行且不容易翻车

通过工具/脚本驱动

通过工具或脚本驱动的方法也是有好几种,这里挑2个我实践过的方案:

通过genie运行

* 这个方法可行,但是不稳定、容易翻车

  1. 安装依赖

    1
    2
    3
    yum install -y dotnet-sdk-3.1 mock perl openssh-server
    wget http://rpmfind.net/linux/epel/7/x86_64/Packages/d/daemonize-1.7.7-1.el7.x86_64.rpm
    rpm -ivh daemonize-1.7.7-1.el7.x86_64.rpm
  2. 安装 genie

    1
    2
    3
    4
    5
    git clone https://github.com/arkane-systems/genie.git
    cd genie/genie
    make
    make install
    ln -s /usr/libexec/genie/main/genie /usr/local/bin/genie
  3. 使用 genie

    1
    2
    genie -s
    systemctl start mysql
  4. 添加开机启动

    1
    2
    3
    4
    5
    6
    vim ~/.bashrc

    #添加以下内容
    if [ "`ps -eo pid,lstart,cmd | grep systemd | grep -v -e grep -e systemd- | sort -n -k2 | awk 'NR==1 { print $1 }'`" != "1" ]; then
    genie -s
    fi

通过wsl-distrod运行

* 这个方法比较贴合我的个人习惯,而且操作简单、运行稳定

  1. 设置wsl默认版本

    1
    wsl --set-default-version 2
  2. 下载distrod最新安装包,解压后打开.exe文件

  3. 根据提示完成distro安装

  4. 在终端里输入以下命令行,windows启动时将自动启用distro

    1
    sudo /opt/distrod/bin/distrod enable --start-on-windows-boot
  5. 以上步骤需要卸载已安装的Linux子系统,如果你不想通过以上方法重装,只需要在终端运行以下脚本(需要挂代理),完成后再执行步骤4的命令行即可。

    1
    2
    3
    curl -L -O "https://raw.githubusercontent.com/nullpo-head/wsl-distrod/main/install.sh"
    chmod +x install.sh
    sudo ./install.sh install