mote 命令

Lobsters Hottest 工具

摘要

介绍 `mote`,一个 Go 命令行工具,可通过 SSH、Tailscale 或其他机制连接远程机器,以运行命令和交叉编译的 Go 测试,并支持上传文件以及与 `go run`/`go test` 集成。

<p><a href="https://lobste.rs/s/gblmih/mote_command">评论</a></p>
查看原文
查看缓存全文

缓存时间: 2026/08/06 06:06

# mote 命令 - rsc.io/cmd/mote - Go Packages 来源:https://pkg.go.dev/rsc.io/cmd/mote Mote 连接到远程机器并运行命令,尤其是交叉编译的 Go 测试。它可以通过多种机制连接:SSH、Gomote、基于 Tailscale 的 TCP 以及经过认证的直接 TCP。 用法: ``` mote [-u path]... [@name] cmd [args...] mote alias [name [URL]] mote clean mote close [URL] mote go-setup mote login URL mote serve URL mote version ``` #### 运行程序¶ (https://pkg.go.dev/rsc.io/cmd/mote#hdr-Running_Programs) 最简单的 mote 命令指定一个主机和要运行的命令: ``` % mote @ssh://kremvax hostname kremvax.uucp % ``` 在命令中,ssh://kremvax 是一个表示要使用的服务器的 URL。下面的“使用 SSH”一节说明了如何设置 kremvax。 一个更有趣的例子是上传并运行交叉编译的 Go 二进制文件。假设 kremvax 是 x86-64 Linux 系统: ``` % GOOS=linux GOARCH=amd64 go build $(go env GOROOT)/test/helloworld.go % mote @ssh://kremvax ./helloworld hello world % ``` 当命令名包含斜杠时,Mote 会将其视为要上传的文件:./helloworld 会被上传,而 hostname 不会。名称的解析方式与在本地运行相同,因此在 Windows 上,“mote ./strings” 会上传并运行 `./strings.exe`。 #### 上传附加文件¶ (https://pkg.go.dev/rsc.io/cmd/mote#hdr-Uploading_Additional_Files) 命令会在一个包含本地目录名的远程临时目录中运行。例如,考虑: ``` % cd /home/rsc/src/myprog % mote @ssh://kremvax ../testprog ``` 在本例中,远程命令可能会在 /tmp/mote-123/home/rsc/src/myprog 中运行,testprog 被上传到 /tmp/mote-123/home/rsc/src/testprog。 可重复的 `-u` 标志指定要上传到远程临时目录树中的附加文件或目录。例如,如果某个测试二进制文件需要 testdata: ``` % cd /home/rsc/src/mypkg % GOOS=linux GOARCH=amd64 go test -c % mote -u ./testdata @ssh://kremvax ./mypkg.test PASS % ``` `-t` 标志会上传 testdata、../testdata、../../testdata 等存在的目录,直到当前 Go 模块根目录: ``` % mote -t @ssh://kremvax ./mypkg.test ``` #### 服务器别名与服务器选择¶ (https://pkg.go.dev/rsc.io/cmd/mote#hdr-Server_Aliases_and_Server_Selection) “mote alias”命令为 URL 定义别名: ``` % mote alias kremvax ssh://kremvax % mote @kremvax ./mypkg.test PASS % ``` 运行“mote alias name”会展开别名: ``` % mote alias kremvax ssh://kremvax % ``` 不带任何参数运行“mote alias”会列出所有已知别名: ``` % mote alias kremvax ssh://kremvax linux-amd64 ssh://kremvax % ``` 每次运行 mote 命令时,它都会发现远程系统的 GOOS 和 GOARCH。如果还没有名为 $GOOS-$GOARCH 的别名,mote 会添加一个指向该系统的别名。在此示例中,mote 定义了一个 linux-amd64 别名。 如果省略“@server”,mote 会依次尝试三种后备方式: - 设置了 $MOTE 时使用 $MOTE。 - 设置了 $GOOS 和 $GOARCH 时使用 $GOOS-$GOARCH。 - 如果可能,根据要上传的二进制文件推导出 $GOOS-$GOARCH,然后使用 $GOOS-$GOARCH。 下面演示全部三种方式: ``` % MOTE=kremvax mote ./mypkg.test % GOOS=linux GOARCH=amd64 mote ./mypkg.test % mote ./mypkg.test ``` #### Go Run 与 Go Test 集成¶ (https://pkg.go.dev/rsc.io/cmd/mote#hdr-Go_Run_and_Go_Test_Integration) Go 工具链通过查找 shell 路径中名为 go_$GOOS_$GOARCH_exec 的运行器来处理交叉编译二进制的“go run”和“go test”。要为所有尚没有运行器的 GOOS-GOARCH 组合创建运行器脚本: ``` % mote go-setup installed 10 hooks in /home/rsc/bin % mote go-setup no hooks left to install % ``` 运行器脚本就是对参数应用“mote -t”: ``` % cat /home/rsc/bin/go_linux_amd64_exec #!/bin/sh exec mote -t "$@" % ``` 脚本没有指定服务器,因此 mote 会使用上面列出的后备方式。在命令行上进行交叉编译会在“go test”传给脚本的环境中设置 $GOOS 和 $GOARCH,从而选择目标系统的别名;如果改用“go env -w”,这些变量会保持未设置,mote 会从测试二进制文件中读取它们。无论哪种方式,隐含的服务器都是 $GOOS-$GOARCH 别名。 为单个命令设置 $MOTE 可以覆盖该选择,指定要使用的别名或 URL: ``` % GOOS=linux GOARCH=amd64 go test strings PASS % MOTE=kremvax GOOS=linux GOARCH=amd64 go test strings PASS % MOTE=ssh://kremvax GOOS=linux GOARCH=amd64 go test strings PASS % ``` 当有多个服务器运行相同的 $GOOS-$GOARCH 时,设置 $MOTE 会很有用。 #### 使用 SSH¶ (https://pkg.go.dev/rsc.io/cmd/mote#hdr-Using_SSH) 要通过 SSH 使用 mote,需要在客户端和服务器上编译并安装 mote,并确认它已加入服务器的 PATH: ``` % go install rsc.io/cmd/mote@latest % ssh kremvax 'go install rsc.io/cmd/mote@latest && mote version' % mote @ssh://kremvax hostname kremvax.uucp % ``` Mote 以启用持久连接且超时时间为 30 分钟的方式运行 ssh,以便重复使用 mote 可以共享一个长期运行的 ssh 连接。具体而言,它运行: ``` ssh \ -o 'ControlMaster auto' \ -o 'ControlPath ~/.ssh/sockets/mote-%r@%h-%p' \ -o 'ControlPersist 1800' \ kremvax \ mote serve - ``` #### 使用 Tailscale¶ (https://pkg.go.dev/rsc.io/cmd/mote#hdr-Using_Tailscale) 通过 SSH 使用 mote 要求服务器可直接访问。Mote 内置的 Tailscale 库消除了这一要求。 要通过 Tailscale 提供 mote 服务: ``` mote serve tail://servername ``` 其中 servername 是所需的服务器名称。 要运行远程命令: ``` mote @tail://servername hostname ``` 客户端或服务器第一次使用 Tailscale 时,需要连接到 tailnet。Mote 会提示输入 Tailscale 认证密钥,然后使用该认证密钥进行注册并获取凭据。它会缓存这些凭据以供后续运行复用。 要创建认证密钥,请打开 Tailscale 管理控制台的“Keys”页面(https://login.tailscale.com/admin/settings/keys),然后点击“Generate auth key”。Mote 使用标签“tag:mote”注册,因此在生成密钥之前,请在 tailnet 策略文件的“tagOwners”部分定义 tag:mote,然后在密钥生成表单上选择 tag:mote。带标签的节点不会附加会过期的人类身份,而且该标签使为 mote 服务器编写网络策略规则变得容易。 服务器在 tailnet 上注册为 mote-servername,客户端注册为 mote-clientname,其中 clientname 是本地主机名的第一个元素。要设置不同的客户端名称,请运行“mote login tail://clientname”。一台机器只会注册一个节点:如果它已经以某个名称登录(无论是通过“mote login”还是“mote serve”),mote 都会使用该登录身份,而不会再次注册。 系统注册后,无论是通过之前的“mote serve”还是显式的“mote login”,“mote serve tail://servername”都可以简写为“mote serve tail:”。 启动 Tailscale 节点需要几秒钟,而 Tailscale 并不期望节点频繁地上下线,因此 mote 会像 ssh 保持连接一样,让节点在后台守护进程中持续运行。第一个需要 tailnet 的 mote 会启动该守护进程;后续的 mote 会发现并复用它,因此只有第一个命令需要为连接付出代价。守护进程在空闲 30 分钟后退出。 Mote 的 Tailscale 客户端完全内置于 mote 二进制文件中,不会重新配置或影响主机网络协议栈。机器上的其他程序不会使用由 mote 管理的 Tailscale 连接。 #### 使用直接 TCP¶ (https://pkg.go.dev/rsc.io/cmd/mote#hdr-Using_Direct_TCP) 如果客户端可以连接到服务器,最简单的机制就是直接 TCP。对于直接 TCP,URL 的形式为 tcp://host:port。客户端和服务器共享一个密码,用于认证连接,并在此基础上建立加密会话。 运行“mote login URL”会提示输入用于某个服务器的密码,并将其保存以供后续运行使用: ``` % mote login tcp://kremlsun:6683 password for tcp://kremlsun:6683: mote: wrote password for tcp://kremlsun:6683 to /home/rsc/.config/mote/password.txt % ``` 每台机器都会保存它用来指代服务器的 URL 所对应的密码,因此客户端和服务器可以以不同的方式命名同一个服务器。服务器使用它所服务的 URL 登录,然后提供服务: ``` % mote login tcp://:6683 password for tcp://:6683: mote: wrote password for tcp://:6683 to /home/rsc/.config/mote/password.txt % mote serve tcp://:6683 mote: serving tcp://kremlsun:6683 ``` 主机可以省略(tcp://:port),表示监听所有接口。mote 命令在开始提供服务时会打印一个完整的 URL。 要运行远程命令: ``` % mote @tcp://kremlsun:6683 hostname kremlsun.arpa % ``` 每个服务器都有自己的密码:登录第二个服务器时会添加一条记录,而不会替换第一条记录。 #### 使用 Gomotes¶ (https://pkg.go.dev/rsc.io/cmd/mote#hdr-Using_Gomotes) Go 项目运行一个名为 gomotes 的自定义远程执行设施,用于访问 Go 自身测试所使用的各种构建器。如果在 PATH 中找到了 gomote 命令,mote 可以使用这些服务器。 要运行远程命令: ``` % mote @gomote://gotip-linux-amd64 hostname TODO % ``` (如果你最近没有使用过 gomote,可能需要先运行“gomote login”。) mote 客户端会在创建 gomote 后安装并启动 mote 服务器。 如果在 PATH 中找到了 gomote 命令,mote 会根据需要创建由 gomotes 支持的 GOOS-GOARCH 别名。例如: ``` % mote go-setup % mote alias linux-arm64 mote: no alias for linux-arm64 % GOOS=linux GOARCH=arm64 go test strings PASS % mote alias linux-arm64 gomote://gotip-linux-arm64 % ``` #### 关闭服务器¶ (https://pkg.go.dev/rsc.io/cmd/mote#hdr-Closing_Servers) 每种传输方式都会让连接保持打开状态,以供下一条 mote 命令使用,超时时间为 30 分钟。要提前关闭这些连接,请使用“mote close URL”: ``` % mote close ssh://kremvax % mote close tail: % mote close gomote://gotip-linux-amd64 mote: destroyed gomote user-gotip-linux-amd64-0 % ``` 不带 URL 运行“mote close”会关闭所有内容:每个共享的 ssh 连接、每个本地 Tailscale 守护进程,以及 mote 创建的每个 gomote 实例。 ``` % mote close mote: closed shared ssh connection to kremvax mote: stopped tailscale daemon for mote-mac mote: destroyed gomote user-gotip-linux-amd64-0 % ``` #### 配置¶ (https://pkg.go.dev/rsc.io/cmd/mote#hdr-Configuration) Mote 将配置存储在用户配置目录下的 mote 子目录中。例如: - Linux 上的 /home/rsc/.config/mote/ - macOS 上的 /Users/rsc/Library/Application Support/mote - Windows 上的 C:\Users\rsc\AppData\Local\mote\ 在该目录中: - aliases.txt 包含别名定义,每行一个别名。 - password.txt 包含与 tcp:// 服务器共享的密码,由“mote login”写入:每行一个服务器,包含服务器 URL 和密码,用空格分隔。 - tail-name/ 是一个目录,保存 tail://name 的登录凭据,以及持有该节点的守护进程的服务套接字、锁和日志。 Tailscale 凭据和 tcp:// 密码都以明文存储,仅受配置目录及其文件的权限保护。 设置 $MOTECONFIG 可以覆盖配置目录的位置。 mote 服务器会在用户缓存目录的 mote/cache 子目录中维护一个内容寻址的上传文件缓存(例如 Linux 上的 /home/rsc/.cache/mote/cache)。设置 $MOTECACHE 可以覆盖缓存目录的位置。每次命令完成后,服务器都会删除超过三小时未使用的缓存文件。运行“mote clean”会删除整个缓存。

相似文章

mvm - 一个快速的 Go 虚拟机

Lobsters Hottest

mvm 是一个快速、可移植的 Go 虚拟机,支持直接从源码运行 Go 程序、嵌入 Go 解释器,并包含 REPL、调试器和标准库。

CodeMote

Product Hunt

CodeMote 是一款 iPhone 应用,可让你远程控制像 Claude Code 和 Codex 这样的 AI CLI 代理。

TailMux

Product Hunt

TailMux 允许用户同时连接多个 Tailscale 网络,无需切换或使用虚拟机。