主页:https://gitee.com/futurelei
脚本仓库:https://gitee.com/futurelei/horus-install
适用系统:Ubuntu / Debian / Fedora / Arch / openSUSE(macOS 部分支持)| 需要 bash

前言

HORUS 是一个面向 Rust / Python / C++ 三语言的实时分布式机器人中间件,官方基准数据相当炸裂:同进程 pub/sub 中位延迟 91ns,跨进程 171ns,比 ROS2 的 DDS 快约 30 倍。它用共享内存环形缓冲区 + 无锁同步替代 DDS,还内置分级看门狗、安全状态钩子和 BlackBox 飞行记录仪——对做实时控制的人来说,这套设计很有吸引力。

但想在国内装上它,第一关就卡死了:

  1. 官方一行安装 curl -fsSL https://raw.githubusercontent.com/... | bash——raw.githubusercontent.com 国内直连基本超时,脚本都下不下来;
  2. 脚本内部要从 GitHub Releases 拉预编译二进制 + SHA256SUMS 校验文件,同样超时;
  3. 兜底方案是从 GitHub 克隆源码编译,git clone github.com 时通时断,浅克隆也要碰运气;
  4. 没有 Rust 工具链的话还要装 rustup,sh.rustup.rs / static.rust-lang.org 国内龟速;
  5. 编译拉 crates.io 依赖不挂镜像,等待时间以小时计。

于是我照着自己之前 dora-rs 一键安装器的思路,给 HORUS 也写了一个 fishros 风格的交互式安装脚本,开源在 Gitee,欢迎大家白嫖 + Star。

一个重要设计约束:这个脚本完全独立于 HORUS 源码仓库,不改源码仓库的任何文件——这样我维护的 gitee 镜像可以放心跟 GitHub 上游同步,永远不会冲突。

一键安装(推荐方式)

方式一:一行命令(fishros 同款体验)

source <(wget -qO- https://gitee.com/futurelei/horus-install/raw/main/horus-install)

回车进入交互菜单,选 1 一键安装,全程自动。

小知识:为什么用 source <(...) 而不是 wget ... | bash
source <(进程替换) 执行时脚本内容走独立的文件描述符,你的终端 stdin 仍然连着脚本,交互菜单才能正常接收按键。fishros 也是这么设计的。

方式二:管道模式(懒人专用)

wget -qO- https://gitee.com/futurelei/horus-install/raw/main/horus-install | bash

脚本检测到自己在管道里执行(stdin 不是终端),会自动跳过菜单直接开始安装,并打印提示告诉你怎么进交互菜单。

方式三:克隆仓库

git clone https://gitee.com/futurelei/horus-install.git
cd horus-install
bash horus-install          # 交互菜单
bash horus-install install  # 非交互直接装

交互菜单功能一览

  ╦ ╦╔═╗╦═╗╦ ╦╔═╗
  ╠═╣║ ║╠╦╝║ ║╚═╗
  ╩ ╩╚═╝╩╚═╚═╝╚═╝   一键安装工具

  [1] 一键安装 HORUS          (推荐)
  [2] 更新 HORUS
  [3] 运行官方示例
  [4] 环境诊断 (horus doctor)
  [5] 卸载 HORUS
  [6] 切换语言 / Switch Language
  [0] 退出

  请输入编号 [默认1]:
  • [1] 一键安装:系统依赖 → Rust 工具链 → cargo 镜像 → 拉源码缓存 → 预编译二进制(可用时)或源码编译 → PATH 配置 → 补全/man 页 → 自动验证,一条龙;
  • [2] 更新git pull --ff-only 拉最新代码重新编译;pull 失败(本地有改动或 shallow 冲突)会自动删缓存重新克隆;
  • [3] 运行官方示例:直接在源码缓存里 cargo run 官方示例(如 01_hello_node),装完立刻能看到东西跑起来;
  • [4] 环境诊断:调用 horus doctor 检查环境;
  • [5] 卸载horus env --uninstall 撤销 shell 集成 → 移除 CLI,源码缓存删不删让你确认,不会误删;
  • [6] 切换语言:中文 / English 双语,按系统 locale 和时区自动选择,菜单里随时手动切换,选择会被记住。

装完第一件事:

horus new my_robot && cd my_robot && horus run

它是怎么做到不卡的

和 dora 安装器同一套优化思路:

  1. 后台异步探测:菜单渲染的同时,探测任务(curl GitHub,3 秒超时)丢到后台跑,菜单立刻显示
  2. 惰性等待:只有真的选了安装,才会去 wait 探测结果——那时你本来就要等下载,3 秒探测无感;
  3. 结果缓存 24h:探测结果写入 ~/.horus-install/cache,重复运行零等待;
  4. 依赖前置检查:apt 依赖先 dpkg -s 查一遍,已装过就完全不碰 apt update
  5. 预编译优先:GitHub 可达时优先下载官方预编译二进制(带 SHA256 校验),跳过整个编译流程;不可达才源码编译(约 3-5 分钟)。

镜像策略:自动切换,也可强制指定

资源 GitHub 可达 GitHub 不可达(国内默认)
源码 github.com/softmata/horus gitee.com/futurelei/horus
rustup sh.rustup.rs rsproxy.cn
crates.io 官方源 rsproxy sparse 镜像
二进制 GitHub Releases + SHA256 校验 无,直接源码编译

探测结果缓存 24 小时,不想等探测的可以用环境变量强制指定:

HORUS_USE_MIRROR=1 bash horus-install install   # 强制国内镜像
HORUS_USE_MIRROR=0 bash horus-install install   # 强制官方源

其它环境变量:HORUS_BUILD_FROM_SOURCE=1(跳过预编译)、HORUS_INSTALL_BRANCH(构建分支,默认 main)、HORUS_NO_SHELL_INTEGRATION=1(跳过 shell 集成)。

HORUS 特有的坑:源码缓存不能删

这是 HORUS 和一般 Rust 工具最大的区别,也是我写这个脚本时踩的最有价值的坑:

horus run / horus build 编译你的机器人工程时,是把 horus 作为 path 依赖直接编译的——CLI 会在固定位置找源码树:~/.horus/cache/horus@<版本>(源码实现见 horus_manager/src/commands/run/run_rust.rsfind_horus_source_dir())。也就是说:

  • 装完 horus 之后删掉源码缓存,你的 Rust 工程就再也编不了了,报的错还是一脸懵的 rustc 错误;
  • 上游 install.sh 为此把源码缓存在 ~/.horus/cache 并且卸载脚本也会询问是否保留;
  • 我的脚本完全遵守这个约定:克隆后解析 horus_core/Cargo.toml 里的版本号,缓存到 ~/.horus/cache/horus@<版本>,CLI 版本对得上就直接复用,对不上才重新拉。

所以如果你看到 horus run 报"HORUS source not found",别慌——重跑一次安装器就好,缓存命中很快就装完。

出问题不用慌:日志自动留存

每个菜单动作的完整输出自动保存到 ~/.horus-install/logs/horus-install-<时间戳>.log,动作开始前打印日志路径,结束后报告成功或失败(带退出码)。退出时全程无报错则日志目录自动清掉,不在主目录留垃圾;一旦有报错则保留。反馈问题时直接把这个文件发我,我能直接定位到哪一步、哪个镜像、哪个依赖出了岔子。

脚本开发实录(替你踩过的坑)

坑 1:半截克隆污染缓存

git clone 偶尔会退出码 0 但树不完整(网络中断、代理抽风)。脚本克隆后先验证 horus/Cargo.tomlhorus_core/Cargo.toml 两个标记文件、解析出版本号,全部通过才移入缓存目录——并且验证在删除旧缓存之前做,坏拉取永远不会覆盖一份能用的缓存。

坑 2:disown 之后 wait %1 会失效

最初照搬 ) & disown + wait %1 的写法,后来发现 disown 把任务从 job 表摘掉后,%1 这个 job spec 就不可靠了,wait %1 静默失败退化成固定 sleep 3。改成记录 $! 的 PID 再 wait "$PROBE_PID",并加了 kill -0 判断避免重复起探测进程。写脚本的朋友注意:要 wait 后台任务,拿 PID,别拿 job spec。

坑 3:LLTO 编译崩溃(沿用了上游的解法)

部分 CPU 上 LLVM 的 LTO 会在 release 构建时 SIGILL 崩溃。上游 install.sh 的处理很聪明:第一次带 LTO 编译失败后设置 CARGO_PROFILE_RELEASE_LTO=off 重试。我直接沿用——两段式编译,第一次失败自动降级,不用用户手动处理。

坑 4:source 运行污染用户终端

和 dora 安装器同款解法:脚本支持 source <(wget ...) 方式运行时,全部逻辑放进子 shell ( main ) 执行set -u 只在子 shell 生效,无论正常退出、Ctrl+C 还是报错都不污染用户终端;还会检测终端是否已被其它工具泄漏了 set -u 状态并主动提示。

无硬编码路径,人人可用

  • 工具链装在 ~/.cargo,二进制装到 ~/.cargo/bin(或 ~/.local/bin),自动写 PATH(fish 用 fish_add_path,不会写出 fish 解析不了的 export);
  • 源码缓存 ~/.horus/cache/horus@<版本>
  • 运行时文件集中在 ~/.horus-install/(日志/缓存/语言偏好),无报错退出自动清空;
  • 非 root 用户自动走 sudo 装系统依赖。

常见问题

Q:装完 horus 命令找不到?
A:新开终端,或先执行 source ~/.cargo/env

Q:编译要多久?
A:GitHub 可达时直接下预编译二进制,几十秒;国内镜像源码编译约 3-5 分钟(机器性能有差异)。

Q:horus run 报找不到 HORUS 源码?
A:~/.horus/cache 下的源码缓存被删了(见上文"HORUS 特有的坑"),重跑安装器即可。

Q:支持 macOS / ARM 吗?
A:脚本检测 uname -s / uname -m,macOS(需 Homebrew)和 aarch64 都能识别;主要测试环境是 Ubuntu x86_64,其它平台欢迎反馈。

Q:为什么国内镜像模式不做预编译下载?
A:预编译包只发布在 GitHub Releases,gitee 镜像同步的是源码。镜像模式下源码克隆本来就快,直接编译反而更省事,还避免了二进制分发的一致性问题。

Q:卸载干净吗?
A:菜单选 5:先 horus env --uninstall 撤销 shell 集成,再移除 CLI;源码缓存是否删除由你确认(提醒:不删缓存下次重装秒装)。

链接汇总

写在最后

这个脚本把「换镜像 → 试下载 → 克隆 → 编译 → 配 PATH → 验证」这套重复劳动固化成了代码,国内用户一条命令就能把 HORUS 跑起来。如果你在做实时机器人控制、或者在给 ROS2 的延迟头疼,HORUS 的 91ns 同进程 IPC 值得一试。

有问题欢迎去仓库提 issue,觉得好用请点个 Star,这是对开源作者最大的鼓励。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐