Lima 实例使用指南:启动、自定义、执行命令与目录挂载全解析
本指南围绕 Lima(Linux virtual machines)中实例的日常使用展开:从
limactl start启动首个实例、通过模板自定义实例配置,到用limactl shell/lima在虚拟机中执行命令,再到宿主 home 目录挂载与用户 shell 的设置。读完本文,你将掌握 Lima 实例从创建到日常操作的全流程,并了解这些操作背后的源码实现机制。
启动你的第一个 Linux 实例
运行 limactl start <INSTANCE> 即可创建并启动第一个实例,其中 <INSTANCE> 是实例名称,缺省时默认为 default。这个默认名称在源码中被显式定义:
// cmd/limactl/main.go
const (
DefaultInstanceName = "default"
...
)
直接在终端中执行:
$ limactl start
? Creating an instance "default" [Use arrows to move, type to filter]
> Proceed with the current configuration
Open an editor to review or modify the current configuration
Choose another template (docker, podman, archlinux, fedora, ...)
Exit
...
INFO[0029] READY. Run `lima` to open the shell.
选择 Proceed with the current configuration(直接使用当前配置继续),然后在宿主终端中等待输出 READY 字样,即表示实例已成功启动。READY 由 hostagent 在实例就绪后打印,随后即可用 lima 打开 shell(见下文)。
交互菜单背后的实现逻辑
上述四个菜单选项并非 UI 层的花架子,而是 limactl start 内部一个完整的状态机。在 cmd/limactl/start.go 中,chooseNextCreatorState 函数通过循环让用户反复选择:
- Proceed with the current configuration:直接返回当前模板配置,进入实例创建流程;
- Open an editor to review or modify the current configuration:调用
editutil.OpenEditor打开编辑器修改 YAML,编辑时文件头部会附带说明,例如“对于 default 实例,多数情况下你无需修改该文件”“若要取消启动,请将该文件保存为空文件”; - Choose another template:列出所有可用模板(
docker、podman、archlinux、fedora等,内部以_开头的模板会被过滤掉,见 filterHiddenTemplates)供重新选择; - Exit:以成功退出码中止。
自动化场景:关闭交互界面
如果需要在脚本或 CI 中自动化创建实例,可以加 --tty=false 禁用交互式用户界面。从 cmd/limactl/main.go 可以看到 --tty 是一个全局标志,默认值取决于 stdout 是否为终端:
rootCmd.PersistentFlags().Bool("tty", isatty.IsTerminal(os.Stdout.Fd()),
"Enable TUI interactions such as opening an editor. Defaults to true when stdout is a terminal. Set to false for automation.")
当 --tty=false 时,loadOrCreateInstance 会走 modifyInPlace 分支,直接应用参数对应的 yq 表达式而不再弹编辑器,并打印日志 Terminal is not available, proceeding without opening an editor。与之等价的是 --yes(-y)标志,它是 --tty=false 的别名,但两者不能同时使用(源码中会直接报错)。
自定义实例:从模板创建
从模板 docker 创建一个名为 default 的实例,再启动它:
limactl create --name=default template:docker
limactl start default
limactl create 的用法是 limactl create FILE.yaml|URL,除了 template:docker 这种内置模板引用外,还支持:
- 本地文件:
limactl create --name=default /usr/local/share/lima/templates/fedora.yaml - 远程 URL(务必使用可信来源):
limactl create --name=default <URL> - 标准输入:
cat template.yaml | limactl create --name=local -(此时--name必填)
相关实现见 cmd/limactl/start.go 中 newCreateCommand 的示例说明。
常用创建参数与 YAML 字段的映射
limactl create / limactl start 继承了 limactl edit 的全部编辑参数(见 cmd/limactl/editflags/editflags.go),这些参数最终都会转换为对实例 YAML 的 yq 表达式。常用的有:
| 参数 | 说明 | 对应 YAML 字段(示例) |
|---|---|---|
--cpus=N |
CPU 数量 | .cpus = N |
--memory=N |
内存大小,单位 GiB | .memory = "NGiB" |
--disk=N |
磁盘大小,单位 GiB | .disk = "NGiB" |
--mount=PATH[:w] |
追加挂载目录,:w 后缀表示可写 |
.mounts = [...] |
--mount-only=PATH[:w] |
覆盖现有挂载 | .mounts = [...] |
--mount-none |
移除所有挂载 | .mounts = null |
--mount-writable |
让所有挂载可写 | .mounts[].writable = true |
--mount-type=TYPE |
挂载类型:reverse-sshfs、9p、virtiofs |
.mountType = "..." |
--plain |
纯模式:禁用挂载、端口转发、containerd 等 | .plain = true |
--containerd=MODE |
containerd 模式:user/system/user+system/none |
.containerd.user/.system |
--vm-type=TYPE |
虚拟机类型(qemu、vz、krunkit、wsl2、hcs 等) | .vmType = "..." |
--arch=ARCH |
架构:x86_64、aarch64、riscv64、armv7l、s390x、ppc64le |
.arch = "..." |
--port-forward=HOST:GUEST[,static=true] |
端口转发 | .portForwards += [...] |
--set='EXPR' |
直接用 yq 表达式修改模板,可多次传入 | 任意字段 |
--param NAME=VALUE |
设置模板参数,可多次传入 | .param["NAME"] = "VALUE" |
需要注意两点:
- 部分参数只对新实例有效。例如
--arch、--plain、--containerd在 YQExpressions 中被标记为onlyValidForNewInstances,对已存在实例传入时会打印提示并跳过(源码提示“Hint: create a new instance withlimactl create --arch=... --name=NAME”)。 - 部分参数被标记为实验性。如
--mount-inotify、--audio-device、--audio-interface,使用时日志会输出--xxx is experimental警告。
--set 的典型用法(来自 limactl create --help 示例):
limactl create --set='.cpus = 2 | .memory = "2GiB"'
注意部分 yq 运算符受限制,详见 limactl help yq-restrictions(对应源码 cmd/limactl/yq_restrictions.go)。
start 命令还额外支持以下标志(见 cmd/limactl/start.go):
--foreground:在前台运行 hostagent(Windows 上不可用);--timeout=DURATION:等待实例进入运行状态的超时时间,默认值定义于instance.DefaultWatchHostAgentEventsTimeout,对 Windows guest 首次启动会自动延长超时;--progress:通过跟踪 cloud-init 日志显示 provision 脚本进度。
更完整的参数清单可在本地运行 limactl create --help、limactl start --help、limactl edit --help 查看(对应命令实现见 cmd/limactl/start.go、cmd/limactl/edit.go)。
在实例中执行 Linux 命令
运行 limactl shell <INSTANCE> <COMMAND> 即可在 VM 中执行任意命令,例如查看内核信息:
limactl shell default uname -a
limactl shell 的实现位于 cmd/limactl/shell.go,底层通过 SSH 连接到实例(使用实例目录下的 ssh.config 与本地转发端口),并构造一段 shell 脚本执行。它支持一系列实用标志:
| 标志 | 说明 |
|---|---|
--shell=SHELL |
指定本次会话使用的解释器,如 /bin/bash |
--workdir=DIR |
指定 guest 内的初始工作目录 |
--preserve-env |
将宿主环境变量传播到 guest(可用 LIMA_SHELLENV_BLOCK 屏蔽、LIMA_SHELLENV_ALLOW 豁免) |
--start |
若实例未运行则先启动 |
--reconnect |
重新建立 SSH 会话(用于清理失活的 control master) |
--sync=DIR |
将宿主目录同步到 guest,退出时再同步回来(要求宿主安装 rsync,且实例不能配置宿主挂载) |
lima 快捷命令与 $LIMA_INSTANCE
对于名为 default 的实例,limactl shell default <COMMAND> 可以简写为:
lima uname -a
lima 是一个 shell 包装脚本(cmd/lima),本质上是 limactl shell --instance "$LIMA_INSTANCE" 的别名。它支持以下环境变量:
$LIMA_INSTANCE:要使用的实例名,默认default;$LIMA_SHELL:guest 内使用的 shell 解释器,默认使用实例内配置的用户 shell;$LIMA_WORKDIR:guest 内初始工作目录,默认是宿主当前目录;$LIMACTL:limactl二进制路径,默认取$PATH中的limactl。
因此你可以用 LIMA_INSTANCE=foo lima uname -a 在非 default 实例上执行命令,也可直接使用 limactl shell --instance=foo uname -a。
limactl shell 在实例未运行时默认会报错并提示先启动,但在 TTY 交互环境下会弹出询问是否立即启动;脚本场景可用 --start 让命令自动拉起实例。
Home 目录:只读挂载与 guest 独立目录
宿主 home 的只读挂载
默认情况下,宿主 home 目录会以只读方式挂载到 guest 中,路径规则为:
- macOS 宿主:
/Users/${USER} - 其他宿主:
/home/${USER}
这个默认挂载定义在模板基础配置 templates/_default/mounts.yaml 中:
mounts:
- location: "~"
其中 location: "~" 即宿主 home,未指定 writable 字段,因此默认只读(Lima 自 v2.0 起不再默认挂载 /tmp/lima,见该文件注释)。
三个与之相关的启动选项:
limactl start --mount-writable:将所有挂载改为可写。底层对应 yq 表达式.mounts<a href="https://link.gitcode.com/i/7039ef9322930b2fbfee9878e96e774f" target="_blank">].writable = true(见 [cmd/limactl/editflags/editflags.go);limactl start --mount-none:禁用所有挂载,对应.mounts = null;limactl start --plain:纯模式启动,除挂载外还会一并禁用端口转发、containerd 等服务。
挂载类型可通过 --mount-type 在 reverse-sshfs、9p、virtiofs 之间选择,底层映射到 .mountType 字段。
guest 独立的 home 目录
guest 内部还有一个独立于宿主挂载的用户 home 目录:
- macOS guest:
/Users/${USER}.guest - 其他 guest:
/home/${USER}.guest(自 Lima v2.1 起) - Lima v2.1 之前:
/home/${USER}.linux
之所以带 .guest / .linux 后缀,是为了避免与宿主 home 的只读挂载点冲突——两个目录在 guest 中各自独立存在、互不干扰。guest 内的下载、缓存等个人文件应写入该独立目录,而不是只读的宿主挂载。
Shell 补全(completion)
Lima 为 limactl 提供了多 shell 的补全能力,相关实现见 cmd/limactl/completion.go。
-
启用 bash 补全:在
~/.bash_profile中加入source <(limactl completion bash) -
启用 zsh 补全:先查看帮助
limactl completion zsh --help,再按提示将输出加入~/.zshrc等配置文件。
启用后,输入 limactl start <TAB> 会补全已存在的实例名与模板名,输入 limactl shell <TAB> 会补全实例名,--cpus、--memory、--disk 等标志还会给出基于宿主硬件推算的候选值(见 cmd/limactl/editflags/editflags.go 中的 completeCPUs 与 completeMemoryGiB)。
设置用户的登录 shell
guest 内用户的默认登录 shell 可以通过以下方式覆盖:
-
实例 YAML 的
user.shell字段:user: shell: /bin/zsh -
命令行标志:
limactl create --shell=/bin/zsh或limactl edit --shell=/bin/zsh。
注意:该 shell 必须已经存在于 guest 镜像中,且必须是绝对路径。这一点由校验逻辑保证——从 pkg/limayaml/validate_test.go 的测试用例可以看到:/bin/bash 合法,而 bash(相对路径)会被拒绝;对 Windows guest 则只接受 cmd.exe、powershell.exe、pwsh.exe 及其绝对路径形式。
对已存在的实例,可以直接在 guest 内使用 chsh 修改登录 shell:
limactl shell default chsh -s /bin/zsh
如果只想在单次会话中使用不同的 shell,而不修改任何配置,使用 limactl shell --shell=SHELL:
limactl shell --shell=/bin/zsh default
在非交互场景下,limactl shell 未指定 --shell 时会优先使用实例配置的 user.shell,否则回退到 guest 内的 $SHELL;Windows guest 则回退到 cmd.exe(见 cmd/limactl/shell.go)。
小结
- 启动实例:
limactl start(缺省实例名default),交互菜单可切换模板或编辑配置,自动化场景用--tty=false; - 自定义实例:
limactl create --name=NAME template:docker,配合--cpus、--memory、--mount-*、--containerd等参数(底层转换为 yq 表达式写入 YAML); - 执行命令:
limactl shell <INSTANCE> <COMMAND>,default 实例可简写为lima <COMMAND>,并支持$LIMA_INSTANCE、$LIMA_SHELL、$LIMA_WORKDIR环境变量; - 目录挂载:宿主 home 默认只读挂载(
--mount-writable改为可写、--mount-none/--plain禁用),guest 独立 home 位于/home/${USER}.guest; - Shell 补全:bash 用
source <(limactl completion bash),zsh 参考limactl completion zsh --help; - 用户 shell:通过
user.shell、--shell或 guest 内chsh设置,单次会话用limactl shell --shell=SHELL。
如需进一步了解实例的 SSH 直连、自动启动等进阶用法,可继续阅读仓库中的 website/content/en/docs/usage/ssh.md 与 website/content/en/docs/usage/autostart.md。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust4.24 K638- DDeepSeek-V4.1-FlashDeepSeek-V4.1-Flash 是一个多模态混合专家(MoE)模型,拥有 5520 亿骨干参数,并支持最多一百万 token 的上下文长度。该模型原生支持图像和文本输入,并以自回归方式生成文本Python640
SlideSCIPPT插件,支持素材库、AI助手、一键添加图片标题,复制粘贴位置、一键图片对齐、一键插入Markdown(加粗、超链接等行内样式、代码块、LaTeX等块级样式)、便捷导出图片!C#170
hello-agents📚 《从零开始构建智能体》——从零开始的智能体原理与实践教程Python52774
new-apiAI模型聚合管理中转分发系统,一个应用管理您的所有AI模型,支持将多种大模型转为统一格式调用,支持OpenAI、Claude、Gemini等格式,可供个人或者企业内部管理与分发渠道使用。🍥 A Unified AI Model Management & Distribution System. Aggregate all your LLMs into one app and access them via an OpenAI-compatible API, with native support for Claude (Messages) and Gemini formats.Go22545
JeecgBoot🔥企业级低代码平台集成了AI应用平台,帮助企业快速实现低代码开发和构建AI应用!前后端分离架构 SpringBoot,SpringCloud、Mybatis,Ant Design4、 Vue3.0、TS+vite!强大的代码生成器让前后端代码一键生成,无需写任何代码! 引领AI低代码开发模式: AI生成->OnlineCoding-> 代码生成-> 手工MERGE,显著的提高效率,又不失灵活~Java36351