我意识到 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/ 目录中。