如何在 WSL2 中启动机器时运行命令

如何在 WSL2 中启动机器时运行命令

我意识到 WSL2 没有负责启动进程的 systemd,但我的目标是在启动 wsl 实例(机器)时运行命令

wsl -l -v
  NAME            STATE           VERSION
* Ubuntu-20.04    Stopped         2
  kali-linux      Stopped         2
  Ubuntu-22.04    Stopped         2

当我启动以下任何一台机器时,如何运行一次命令

我尝试编辑/etc/wsl.conf并添加以下内容

[boot]
command="ping 10.0.0.8 && service docker restart "

但这似乎没有帮助,我没有在 IP 上看到任何东西10.0.0.8

我尝试使用编辑 cron 作业,crontab -e但由于上面提到的原因,这不起作用

我使用命令启动机器wsl --distribution Ubuntu-20.04,然后使用以下命令终止它们wsl --shutdown,但这似乎不会导致wsl.conf运行command

答案1

几点指示...

首先,你没有提到你正在运行哪个 Windows 版本。Windows 11 是使用 WSL[boot]功能所必需的/etc/wsl.conf 更新说明:不再如此。请参阅这个答案了解详情)

但即使你使用的是 Windows 11,你的示例仍然会存在一些问题:

[boot]
command="ping 10.0.0.8 && service docker restart "

首先,ping 10.0.0.8正如您所指出的,是一个交互式命令。command执行的无法访问终端,因此如果您想捕获结果,则需要重定向输出。

其次,ping在正常情况下,通常会“永远运行”。ping永远不会“完成”,因此您的service docker restart被执行。您可以在命令行中重现同样的事情。

第三,由于启动command仅在 WSL 实例启动时执行一次,因此实际上不需要service ... restart。也许这不是什么大问题,因为如果还没有,restart通常会这样做,但我start思考我见过一些服务脚本,restart如果服务当前未启动,它们会拒绝。我不记得 Docker init 服务是如何编写脚本的。

步骤 1:捕获 ping 输出

因此(假设您使用的是 Windows 11),首先尝试:

[boot]
command="ping 10.0.0.8 >> /var/log/mybootping.log"

退出你的 Ubuntu/WSL2 实例,然后从 PowerShell 中:

wsl -l -v
# Confirm your distribution name -- Change it below if needed
wsl --terminate Ubuntu-20.04
wsl ~ -d Ubuntu-20.04

然后,检查cat /var/log/mybootping.log。您应该会看到 ping 的结果。请注意,它将继续运行,并且日志会不断增长,直到您退出实例或kill进程ping

第 2 步:允许 ping 退出

您可以通过将命令更改为ping -c 4 10.0.0.8仅重复 ping 4 次来限制此操作。这样,ping它将自行退出。

步骤 3:捕获 ping 错误

但假设你输入了错误的命令行:

[boot]
command="ping -c 10.0.0.8 >> /var/log/mybootping.log"

哎呀,我忘记了标志的重试次数-c。注意——我实际上做过测试时犯了这个错误。但/var/log/mybootping.log没有得到输出,因为它进入了 stderr 而不是 stdout。

最好这样做:

[boot]
command="ping -c 4 10.0.0.8 >> /var/log/mybootping.log 2>&1"

这将捕获/附加错误并输出到日志。

步骤4:添加Docker服务

此时,ping可以使用参数退出-c,您可以添加 Docker 服务。

[boot]
command="ping -c 4 10.0.0.8 >> /var/log/mybootping.log 2>&1 && service docker start"
步骤 5:捕获输出和错误两个都ping 和服务

但如果你只是想捕捉全部启动命令的输出?

[boot]
command="exec 1>>/var/log/wslboot.log && exec 2>&1 && echo -------------------- && date && ping -c 4 10.0.0.8 && service docker start"

对于 Windows 10

如果您没有 Windows 11,那么如上所述,您将无法使用该[boot]功能wsl.conf

您可以:

  • 将命令添加到您的用户,~/.bashrc正如我在这个答案

  • 为 WSL 手动运行一次性“启动”命令。例如,从 PowerShell:

    wsl ~ -u root -d Ubuntu-20.04 -e sh -c "ping -c 4 10.0.0.8 && service docker start"
    

    由于在这种情况下会出现输出,我们可以跳过命令中使用的所有输出/错误捕获[boot]

    如果你有一个不分叉的服务(后台本身),比如dockerd(来自评论),那么你需要用 来执行它nohup。类似的东西:

    wsl ~ -u root -d Ubuntu-20.04 -e nohup sh -c "dockerd &"
    

    任何输出都将在 中/root/nohup.out。如果你想将其定向到其他地方,事情就会变得有点复杂:

    wsl ~ -u root -d Ubuntu-20.04 -e sh -c "nohup sh -c 'dockerd &' >> /var/log/dockerd-nohup.out"
    

    我可能错了,但我相信 WSL 有一个错误,这会让事情变得更加困难。据我所知,WSL 在将 shell 的孤立子进程(尚未)收割到 方面过于激进init

答案2

您可以使用.bashrc 或.profile。

当启动 WSL 提示时,这些文件位于用户的 /home/ 目录中。

相关内容