从控制台重新启动 WSL

从控制台重新启动 WSL

如何从 WSL 控制台重新启动当前的 WSL 实例?

通常的“嫌疑人”不起作用:

reboot
shutdown -r

他们失败并显示以下消息:

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

还有其他方法可以强制 WSL 重新启动吗?

答案1

您需要通过 Windowscmdpowershell使用以下命令来执行此操作:

> wsl --shutdown

如果您有大量实例并且需要关闭特定实例或发行版,您可以使用;

> wsl -l -v

查看发行版名称、状态(无论是运行还是停止)和wsl版本并使用

> wsl -t NAME

答案2

以下内容适用于我在 Linux 中的 Windows 11 下使用 WSL2:

sudo poweroff -f

这会直接关闭 Linux 内核,而无需尝试通过 SystemD 之类的缺失来实现init

请注意,这可能需要一些时间(至少8秒,但我也观察了1min)直到实例可以再次启动。同时,当您尝试访问该实例时,您将观察到类似以下内容(这也来自德语 Windows 安装,Windows 终端也设置为德语):

Schwerwiegender Fehler
Error code: Wsl/Service/E_UNEXPECTED

[Verarbeitung des Prozesses mit Code 4294967295 (0xffffffff) beendet]

不用担心。只需坐下来稍等一下,然后再试一次。

如果你好奇:

strace poweroff -f

展示了它是如何工作的。您看到的最后几行将类似于:

sync()                                  = 0
reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_CAD_ON) = -1 EINVAL (Invalid argument)
writev(2, [{iov_base="Powering off.", iov_len=13}, {iov_base="\n", iov_len=1}], 2Powering off.
) = 14
reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_POWER_OFF) = ?
+++ exited with 0 +++

[Verarbeitung des Prozesses mit Code 1 (0x00000001) beendet]

答案3

首先,重要的是要了解,当您在 WSL 中运行 Linux 发行版时,它与在物理机甚至虚拟机上运行不同。您实际上所在的是一个容器,使用与 Docker 或大多数其他容器系统类似的技术(命名空间、cgroup 等)。

尝试“关闭”WSL 发行版就像尝试“关闭”Docker/Podman/其他容器一样。如果 Ubuntu 在 Docker 中运行,您不需要从 Ubuntu 中关闭它,而是可以通过以下任一方式关闭它:

  • docker stop从容器外部执行命令
  • 或者简单地退出容器内所有正在运行的进程

WSL 也是如此。您可以:

  • 停止发行版中所有正在运行的进程,退出所有交互式 shell,WSL 应在 15 秒后自行终止发行版。但请注意,Docker Desktop 将使任何发行版保持运行,因为其后台进程会继续运行。

  • 强制终止分发。虽然这通常是通过 PowerShell 或 CMD 完成的wsl --terminate <distroname>,但也可以从里面分布使用:

    wsl.exe --terminate $WSL_DISTRO_NAME
    
  • 使用 完全关闭 WSL 系统wsl --shutdown。同样,在 WSL 内部,必须使用带扩展名的完整可执行文件名称,因此wsl.exe --shutdown

请注意,任何--terminate--shutdown强制停止分发。这是不是优雅的终止。所有正在运行的进程将立即结束,没有机会响应任何正常信号。

为了正常关机(复制我的 AU 答案这里),根据 Windows 11 中最新的 WSL 版本,您现在运行Systemd。 WSL2 下 Systemd 启动的服务会在以下情况下自动终止:没有其他进程(本质上除了由 Systemd 启动的那些)都在 Ubuntu 中运行。

此次停产优美。 WSL2 与 Systemd 通信,使其正常停止(通过正常的 Systemd 信号行为)在其下运行的任何服务。

这仍然不一定是最佳的,因为您需要在后台运行一个额外的进程(“交互”启动)以保持 WSL 同时运行。看这个答案有关如何执行此操作的解决方案。如果您使用像keychain我在那里提到的那样的东西,那么您只需要停止该进程(keychain -k all),退出 Ubuntu 中的 shell,并且在 15 左右的时间内 WSL2 应该向 Systemd 发送“正常关闭”信号。

相关内容