我刚刚从 Microsoft Store 购买了 Ubuntu,并尝试了一些功能。但是当我尝试使用或重新启动或关闭系统时sudo reboot
,sudo shutdown -h
我收到一条提示说
“系统尚未使用 systemd 作为 init 系统 (PID 1) 启动。无法操作。无法与 init 守护进程通信。”
这是否意味着由于机器在 WSL 下,我无法简单地关闭它?
每次我想退出时,我是否必须按 X 键?
我已获得 Windows 和 Ubuntu 的最新更新。
答案1
我知道这已经过时了,但我刚发现你可以通过 powershell 来做到这一点
列出分布:
wsl --list
将输出类似
Windows Subsystem for Linux Distributions:
Ubuntu (Default)
docker-desktop-data
docker-desktop
终止Ubuntu
wsl --terminate Ubuntu
或终止所有
wsl --shutdown
希望这可以帮助!
答案2
有时wsl --shutdown
似乎不起作用,比如运行这些命令:
wsl --shutdown
wsl -l -v
导致一些容器仍然在运行:
NAME STATE VERSION
* docker-desktop-data Stopped 2
docker-desktop Stopped 2
Ubuntu-20.04 Running 2
事实证明,当您尝试访问 WSL 驱动器时,WSL 实例会自动启动。就我而言,\\wsl$\Ubuntu-20.04\workspace
是在 IDE 中打开的,这导致实例在关闭后立即重新启动。关闭 IDE 后,我能够正确关闭 WSL。
编辑:
这实际上是一个非常好的功能,我不需要手动启动 WSL,我只需打开我的 IDE,它就会找到所需的驱动器。
答案3
这里有一些很好的答案,我不想再添加另一个,但我认为他们都缺少一些相当基本的东西——WSL 实例将自动地当没有进程运行时终止。
正如我(更详细地)指出的那样这个 Github 讨论,有两个计时器控制 WSL 何时终止或关闭:
当分发/实例内部没有进程运行时
/init
,分发将终止。这相当于wsl.exe --terminate $WSL_DISTRO_NAME
。此计时器被硬编码为 15 秒。如果该状态下没有运行任何 WSL2 发行版
RUNNING
(如 所示wsl.exe -l -v
),则 WSL2 VM 本身将关闭。这相当于wsl.exe --shutdown
。
所以实际上,在大多数情况下,没有必要手动调用任何其他命令来关闭 WSL。
我每次想要退出时都要按 X 吗?
如果您愿意,可以这样做。当终端窗口关闭时,shell 及其中运行的任何进程也将关闭。几秒钟后,如果没有进程正在运行,WSL 将根据上面提到的计时器自动终止实例。
但是,您只需退出 shell 即可完成相同的操作(假设没有后台进程正在运行)。exit
Enter在大多数情况下,键入或Ctrl+D即可退出 shell。同样,几秒钟后,如果实例中没有其他进程正在运行,WSL 将自动终止它。
你可以通过做一些简单的事来看到这一点:
- 启动 WSL Ubuntu
- 在 PowerShell 或 CMD 中运行
wsl -l -v
。“Ubuntu”实例将显示为“正在运行” - 在你的 shell 中(可能是 Bash),只需按Ctrl+D
- 再次快速运行
wsl -l -v
,Ubuntu 实例可能仍会显示“正在运行” - 等待 20 秒,
wsl -l -v
再次运行,Ubuntu 实例可能会显示为“已停止”
如果没有,则可能仍有某些程序在运行。您可以使用wsl -e ps aux
(同样,从 PowerShell 或 CMD)进行检查。如果没有其他程序在运行,您将看到两个init
进程和ps
仅该进程:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 8940 316 ? Ssl 19:34 0:00 /init
root 6 0.0 0.0 8940 224 tty1 Ss 19:34 0:00 /init
username 7 0.0 0.0 17392 1904 tty1 R 19:34 0:00 ps auxw
如果出现其他情况,那么 WSL 可能不会自动终止实例。
wsl.exe --terminate Ubuntu
在这种情况下,Pablo 的出色回答就派上用场了。您可以通过(或您的发行版的任何名称)强制终止实例。实例内的所有进程都将被终止。
或者(Pablo 也介绍过),你可以使用 关闭整个 WSL 系统wsl.exe --shutdown
。这将关闭所有实例(以及其中运行的进程)以及网络系统和互操作。在 之后启动新的 WSL 实例时,你会注意到延迟会稍微长一些--shutdown
。
关机自里面Ubuntu
请注意,这也可以适用于里面Ubuntu/WSL 只需调用wsl.exe
而不是 即可wsl
。这将终止当前正在运行的 WSL 发行版:
wsl.exe --terminate $WSL_DISTRO_NAME
这将关闭全部运行发行版和 WSL2 VM 本身(从 Ubuntu 内部):
wsl.exe --shutdown
但请注意,这些都是不是“优雅”关闭。所有仍在运行的进程将立即地终止且没有改变以响应任何信号。
Windows 11 下的优雅关机
在 Windows 11 中最新的 WSL 版本中,你能现在运行 Systemd. WSL2 下由 Systemd 启动的服务在以下情况下会自动终止:没有其他进程(本质上除了由 Systemd 启动的那些)都在 Ubuntu 中运行。
此次停工是优雅。WSL2 与 Systemd 通信,让其优雅地停止(通过正常的 Systemd 信号行为)在其下运行的任何服务。
这仍然不是最佳选择,因为你需要在后台运行一个额外的进程(以“交互方式”启动)以保持 WSL 同时运行。请参阅这个答案了解如何执行此操作的解决方案。如果您使用keychain
我在此处提到的类似方法,则只需停止该进程 ( keychain -k all
),退出 Ubuntu 中的 shell,大约 15 分钟内 WSL2 就会向 Systemd 发送“正常关机”信号。
为什么正常的 Linux 关机机制在 WSL 中不起作用
那么为什么正常的reboot
/shutdown
命令不起作用? 主要因为 WSL 下的 Ubuntu 不是在物理机或虚拟机中运行的。你运行的实际上是 Ubuntu容器在里面管理(换句话说,我们通常无法直接与它交互)WSL2 VM。
尝试“关闭” WSL 发行版就像尝试“关闭” Docker/Podman/其他容器一样。如果 Ubuntu 在 Docker 中运行,则不能从 Ubuntu 关闭它,而是通过以下方式关闭:
- 执行
docker stop
来自外部容器 - 或者直接退出所有正在运行的进程里面容器
WSL 也一样。
答案4
systemd 支持尚未实现。我发现最好的方法是重新启动整个 WSL 子系统:以管理员身份启动 cmd shell 并
net stop LxssManager
net start LxssManager