# mybox **Repository Path**: graviton/mybox ## Basic Information - **Project Name**: mybox - **Description**: my busy box tools - **Primary Language**: Unknown - **License**: AGPL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-02 - **Last Updated**: 2026-11-03 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # mybox 给共享工具目录 `/data/cmbin` 用的小工具箱. 目前只有一个程序: **myboxup** —— `/data/cmbin` 的更新器/装配器. ## myboxup 这堆共享二进制以前是靠人肉逐个去 GitHub Release 页面下载、解压、放进目录, 没有版本记录, 也没人说得清哪个是什么时候放的、来自哪个 repo. myboxup 把这件事变成一份可读的清单 + 一条命令. 一份 `myboxup.toml` 声明"哪个工具、来自哪个 repo、取哪个资产、装成什么名字", myboxup 负责查 release、挑资产、下载、解压、原子安装, 并把装了什么版本记进 lock 文件. ```bash myboxup list # 清单条目 + 已装版本 myboxup check # 查最新 release, 与 lock 对比 (不下载) myboxup check zellij yq # 只查指定几个 myboxup install # 安装/更新清单里所有工具, 已最新则跳过 myboxup install --dry-run # 只看会做什么 myboxup install --force yq # 忽略 lock 强制重装 myboxup doc # 生成 TOOLS.md 目录页到 bin_dir ``` ### 改 asset 之前, 先去暂存目录验真 改动某个工具的 `asset` 后不要直接往共享目录装 —— 先装到别处跑一遍: ```bash myboxup -dir /tmp/stage install --verify rg fd bat ``` `--verify` 会把装好的二进制真的执行一次 (`--version`), 跑不起来就报错并计入失败。 这一步不是形式主义, 实际拦下过两类问题: - **glibc 太旧**: 上游只发动态链接 gnu 版, 本机 CentOS 8 是 glibc 2.28, 装上直接 `GLIBC_2.33 not found`。文件在、版本号也记进了 lock, 但根本跑不起来。 - **名字带 musl 不等于静态链接**: marksman 的 `marksman-linux-musl-x64` 是*动态*链接到 `/lib/ld-musl-x86_64.so.1`, glibc 主机上没这个 ELF 解释器, 表现为莫名其妙的 "no such file or directory" —— 反倒是 gnu 版能跑。 所以选资产的顺序是: 优先 musl, 但一律以 `--verify` 的实测结果为准。 默认会依次试 `--version` / `-V` / `version`, 有一个能跑通就算过. 个别工具三个都不认 (比如 7zz 只在无参数时打印版本), 用 `verify_args` 指定: ```toml verify_args = [] # 空列表 = 不带参数运行; 也可写 ["-h"] 之类 ``` ### 清单格式 ```toml bin_dir = "/data/cmbin" [tools.zellij] group = "会话与任务" # TOOLS.md 里的分组 added = true # 在 TOOLS.md 里标 🆕 repo = "zellij-org/zellij" asset = "zellij-no-web-x86_64-unknown-linux-musl.tar.gz" # 支持 * 通配 bins = { "zellij" = "zellij" } # 归档内成员 -> 安装名 desc = "终端复用器 ..." # 一两句说明, 进 TOOLS.md ``` - `asset` 是 glob, 对 release 资产名匹配. 多个命中时取名字最短的那个 (通常是主资产而非附带的校验和). 写成通配是为了让带版本号的资产名 (`just-1.57.0-x86_64-...`) 不用每次升级都改清单. - `bins` 的键按归档内路径的 **basename** 匹配, 因此不用关心归档里套了几层目录. 只列你要的那个 —— 比如 ast-grep 的归档里还有个 `sg`, 装进去会盖住系统的 `/usr/bin/sg`. - 资产不是归档 (裸二进制或单文件 `.gz`) 时可以省掉 `bins`, 装成工具名; 要改名就写 `bins = { "*" = "tldr" }`. - 支持的归档: `.tar.gz` / `.tgz` / `.tar.xz` / `.zip` / `.gz` / 裸二进制. - `skip = true` 的条目 myboxup 不碰, 只用来生成文档 —— 目录里那些历史遗留的、由工具作者自己维护的二进制都是这样登记的. 全部字段: | 字段 | 层级 | 说明 | |---|---|---| | `bin_dir` | 顶层 | 安装目标目录; `TOOLS.md` 与 `.myboxup.lock.json` 也落在这里 | | `groups` | 顶层 | `TOOLS.md` 里的分组显示顺序; 没列到的分组排在最后 | | `repo` | 工具 | GitHub `owner/name`, 版本号从它的 release tag 读 | | `asset` | 工具 | release 资产名 glob; 多个命中取最短的那个 | | `bins` | 工具 | 归档内成员 → 安装名; 裸二进制/单 `.gz` 可省 | | `desc` | 工具 | 一两句说明, 进 `TOOLS.md` | | `group` | 工具 | 它在 `TOOLS.md` 里的分组标题 | | `added` | 工具 | 在 `TOOLS.md` 里标 🆕 | | `tag` | 工具 | 钉死某个版本; 不写 = 跟 latest | | `skip` | 工具 | 不管理, 只登记进文档 | | `cargo` / `cargo_bin` | 工具 | 改为 `cargo install `; 产出的二进制名与工具名不同时用 `cargo_bin` | | `note` | 工具 | 额外说明 (如为何要从源码构建), 进 `TOOLS.md` | | `url` | 工具 | 非 GitHub 来源的主页 (codeberg / sourceforge / 内网 gitea); 不写则由 `repo` 推出 GitHub 链接 | | `verify_args` | 工具 | `--verify` 用的参数; 见上面一节 | ### 从源码构建 少数工具上游只发 glibc 动态链接的 Linux 资产, 而这些服务器是 CentOS 8 (glibc 2.28), 下载下来跑不起来 (`GLIBC_2.33 not found`). 这类工具在清单里写 `cargo` 就改为本地编译: ```toml [tools.jless] repo = "PaulJuliusMartinez/jless" cargo = "jless" # 走 cargo install, 不下载资产 note = "上游只发 linux-gnu 资产, 需 GLIBC_2.33 而本机是 2.28, 故从源码构建." ``` 版本号仍然从 GitHub release tag 读, 所以 `check` 和 lock 的逻辑不变. ### 安装是原子的 先写到目标目录下的临时文件、chmod、再 `rename` 覆盖 —— 同一文件系统内的 rename 是原子的, 所以不会出现"下到一半的半截二进制"; 正在运行的旧进程也不受影响. ### 状态记在哪 `/.myboxup.lock.json` 记录每个工具装的 tag、资产名、时间和落地的文件名. 它放在目标目录而不是本仓库, 这样共享目录的状态是自描述的 —— 换台机器看同一个目录就知道装了什么. `myboxup doc` 生成的 `/TOOLS.md` 是给人看的目录页, 由清单 + lock 拼出来. ## 构建与部署 ```bash go run build.go # 构建到 ./build/myboxup go run deploy.go # 把 myboxup 和清单放到 /data/cmbin 与 ~/bin, 再重生成 TOOLS.md ``` `build.go` / `deploy.go` 是只用标准库的单文件, 不需要先编译它们; `-n` 都是预演。 常用参数: ```bash go run build.go -t linux/arm64 # 交叉编译 (可重复 -t); -all = 六个常规目标 go run build.go -vet -test # 构建前过 go vet / go test go run deploy.go -no-doc # 不重新生成 TOOLS.md go run deploy.go -no-config # 只更新二进制 (清单留目标目录里那份) go run deploy.go -t /tmp/try -mkdir # 换目标 (可重复给) ``` 清单需要和二进制一起部署: myboxup 找清单的顺序是 `-m 参数` → `$MYBOXUP_MANIFEST` → 可执行文件同目录 → 上级目录 → 当前目录。 仓库里的 `myboxup.toml` 是主本, 部署会覆盖目标目录里的副本 —— 别手改副本。 `TOOLS.md` 是 `myboxup doc` 的生成物, 部署完会用**刚装好的那份** myboxup 重新生成到 清单的 `bin_dir` 下; **不再同步回仓库**(生成物留一份就够, 两份只会多一个"哪份是新的" 的问题)。仓库里现存的 `TOOLS.md` 是当时的快照, 之后不再自动刷新。 部署比 `cp` 多做三件事: 先验产物是不是 Linux x86-64 ELF(`/data/cmbin` 整棵树会被 `chmdply push --task cmbin` 分发到十几台机器); 写入走临时文件 + 原子改名(目标正被 执行时 `cp` 会 `ETXTBSY`); 内容相同则不动。旧的 `deploy.sh` 已挪到 `backup/`。 ## 环境 - `GITHUB_TOKEN` — 可选。未认证时 GitHub API 限额是 60 次/小时, 一次 `check` 每个工具用一次, 工具一多就不够。也可以写进 `~/.config/myboxup/token` (权限必须是 `600`, 否则会被拒绝读取并提示)。 - 代理沿用 `https_proxy` 等环境变量 (Go 标准库默认读)。 ## 已知的边角情况 - **`.tar.xz` 的过滤器链**: 纯 Go 的 xz 解码器只认单一 LZMA2 过滤器。7-Zip 自己的 release 用了 BCJ x86 + LZMA2 的链, 会报 `unsupported filter count`; 这时 myboxup 自动回退到 系统的 `xz` / `7zz` 命令。 - **`sd` 自报版本比 tag 旧** (tag `v1.1.0`, 二进制说 `1.0.0`) —— 上游自己的问题, 不影响使用。 - **不接管的工具**都在清单里标了 `skip = true` 并写明原因, 见生成的 `TOOLS.md`: 代理内核 (mihomo/xray, 自动升级碰上配置格式变更会让所有人断网)、 需要整棵目录树的 (helix 的 runtime/、nvim)、 不在 GitHub 的 (mergiraf 在 codeberg, sshpass 在 sourceforge)、 以及内部自建的 (rpdf/synctools/chmdply)。 - `pre-adopt-versions.txt` 记录了接管前各工具的版本, 需要回滚时在清单对应条目加 `tag = "<旧 tag>"` 再 `myboxup install --force <名字>`。