目录
1、目标
windows后台静默启动wsl、wsl里的docker服务、docker服务里的指定容器(容器已存在).
(我的wsl虚拟linux用户:cf/ cf123456。如果忘记用户密码,可参考 linux用户信息查询_风路丞的博客-CSDN博客)
2、操作
要实现这个目标可以分2步完成:
step1: 让docker服务、docker服务里的指定容器能够在wsl2启动时也被自动加载运行;
step2: 使wsl2启动窗口能够后台隐藏。
2.1 wsl2里后台启动docker和指定容器
(1)启动WSL2
打开任意cmd、powershell、linux图标或ubuntu图标,输入wsl。
(2)修改.bashrc文件
step1:打开文件
nano ~/.bashrc 或 vim ~/.bashrc
step2:文件编辑
方案一:直接追加
在~/.bashrc文件的末尾添加指令:
# 启动 Docker
sudo service docker start
# 启动指定的 Docker 容器openai_api
docker start openai_api
缺陷:如果你想另起一个wsl做些别的工作,发现docker服务和指定容器又再次被重启了。
方案二: 先判断再执行
在~/.bashrc文件的末尾添加指令:
# 检查Docker进程(dockerd是Docker的守护进程,管理着Docker的所有容器和网络。)是否已经在运行
if ! pgrep -x "dockerd" > /dev/null
then
# 如果Docker进程没有运行,那么启动Docker
service docker start
fi
# 检查指定的Docker容器是否已经在运行
if [ ! "$(docker ps -q -f name=openai_api)" ]; then
if [ "$(docker ps -aq -f status=exited -f name=openai_api)" ]; then
# 如果指定的容器已经存在,但是没有运行,那么重启该容器
docker restart openai_api
else
# 如果指定的容器不存在,那么启动一个新的容器
# 这里只输出常数
echo 1
fi
fi
这样,就可以保证docker服务和指定容器只被启动一次了。
step3:退出nano
先按 Ctrl+O(或 Ctrl+X 直接选择保存)来保存你的更改。这时候在底部会出现一个提示,让你确认文件名,直接按 Enter 即可。
再按 Ctrl+X 来退出 nano 编辑器。
(3)无密码执行sudo命令
因为第(2)步中涉及 root 权限,所以要编辑 sudo 的配置,使其可以无密码执行root权限:
# 打开sudo
sudo visudo
# 然后在文件的末尾添加一行如下的命令:
your_linux_username ALL=(ALL) NOPASSWD: /usr/sbin/service
退出:仍是nano的退出方式。
风险:这种方法可能会带来安全风险,因为它允许某些命令在不需要密码的情况下以 root 权限运行。在实际使用时,请谨慎考虑。
(4)测试
step1: 先关闭之前的docker服务、停掉容器openai_api。
step2:再重新打开一个wsl2,发现docker和openai_api被自动启动啦!
step3:再次验证:在当前窗口内执行docker ps,发现容器openai_api的确是up状态。
step4: 验证容器内的服务是否可用
telnet localhost 8500
2.2 后台启动WSL2
由于我的docker容器里的服务需要被其他主机访问,所以需要先配置端口映射,具体参考如何在局域网的其他主机上中访问本机的WSL2 - 知乎 (zhihu.com) 。这里我选用启动wslpp.exe的方式。
(1)编写powershell脚本
脚本内容如下,保存为startup.ps1。
# 以管理员权限 启动wslpp.exe程序
Start-Process "D:\worksoft\WSL\wsl2-protproxy\wsl2-auto-portproxy\dist\wslpp.exe" -WindowStyle Hidden -Verb RunAs
# 等待wslpp.exe程序启动成功
do {
Start-Sleep -Seconds 1
} until (Get-Process "wslpp" -ErrorAction SilentlyContinue)
# 启动WSL
Start-Process -FilePath "wsl" -WindowStyle Hidden -Verb RunAs
其中:
powershell指令写法默认驼峰,但也支持全大写和全小写。
- WindowStyle Hidden 表示窗口隐藏;
- -Verb RunAs 表示以管理员权限执行命令;
- -FilePath 可写可不写
- Start-Process 表示启动一起新进程。
(2)以管理员身份运行shell脚本
Start-Process powershell -ArgumentList "-ExecutionPolicy Bypass -File `"shell脚本地址`" -WindowStyle Hidden" -Verb RunAs
eg:
Start-Process powershell -ArgumentList "-ExecutionPolicy Bypass -File `"D:\runback\startup.ps1`" -WindowStyle Hidden" -Verb RunAs
其实在启动命令中已经使用了-Verb RunAs,那在startup.ps1中的每行命令都会被以管理员身份运行,但是,这需要用户手动确认UAC(用户帐户控制)提醒。如果你在隐藏的窗口中启动进程,那么这个UAC提醒可能会被隐藏,所以无法得到用户的确认。
所以脚本中静默启动wslpp、wsl仍要特别指定-Verb RunAs。
有个疑问:
问:为什么wsl明明是不需要管理员就可以启动的,但写在这个脚本里后,就必须以管理员才能启动
答:这与PowerShell的执行环境有关。在脚本中执行命令时,它的行为可能会和在交互式shell中执行命令有所不同。比如,脚本可能在一个不同的用户上下文或环境变量设置中运行。
如果你的脚本在一个没有管理员权限的上下文中运行,那么它可能无法启动需要管理员权限的进程。即使你在交互式shell中可以以非管理员用户启动WSL,但在脚本中可能就无法做到。
3、powershell指令
1、进程查看
Get-Process -Name[可不写] 进程名
eg: Get-Process wsl
Get-Process powershell
2、杀死指定进程
Stop-Process -Id PID
eg: Stop-Process -Id 1234x
通过以上命令可以查看wsl、wslpp是否正常启动。