rlwrap 是一个命令行包装工具,借助 GNU readline 库,为本身不具备行编辑能力的命令提供键盘输入编辑、跨会话持久的历史记录与补全。它在启动目标命令时拦截用户输入,把 readline 的行编辑、历史检索和补全能力附加到该命令上,而对命令本身不作修改。历史记录按命令分别保存,并可在多次调用之间延续。
定义
rlwrap 是一个使用 GNU readline 库的小型工具,作用是让任意其他命令的键盘输入也能被编辑[1]。它通常以在命令行中位于目标命令之前的形式使用,语法为 rlwrap 加若干选项再加命令及其参数[2]。
该工具的设计目标之一是尽量做到透明:除了多出来的 readline 功能,用户或 shell 不应察觉到命令与经 rlwrap 包装的命令之间有何差别;这一特性在重定向、管道传送信号,以及命令改换自身终端设置、工作目录或命令行时也应当成立[2]。
原理
终端上的控制台命令一般处于两种输入模式:规范模式(cooked)下要按下回车键才把整行交给程序,原始模式(raw)下每次按键都立即被送出。前一种模式通常可以用退格键修改输入,却不能用方向键[2]。
执行 rlwrap 命令时,rlwrap 会在独立会话中运行目标命令,并为它分配一个受控的伪终端(pty),随后监视该伪终端处于原始模式还是规范模式。处于原始模式时,rlwrap 在命令与用户终端之间直接转发输入输出,称为直接模式;处于规范模式时,rlwrap 用 readline 编辑用户输入,称为 readline 模式[2]。
在 readline 模式下,命令输出中每一行不以换行符结尾的末行都被视为可能的提示符。为区分提示符与普通输出,rlwrap 在收到这样的末行后会等待一小段时间,默认是 40 毫秒,可用 -w 选项调整。默认情况下它先原样显示可疑提示符,等待结束后再替换为处理过的版本,这种方式称为不耐烦模式;若给 -w 传入负值,则改为等处理完毕后再显示提示符,称为耐心模式[2]。
确定提示符后,rlwrap 会依次对其施加过滤、替换和着色处理,得到所谓处理过的提示符再输出;过滤由 -z 指定,替换由 -S 指定,着色由 -p 指定[3]。过滤器是小型 Python 或 Perl 脚本,可用来改写或抑制输入、输出、提示符、历史条目乃至信号,常被用于把敏感输入排除在历史之外、实现简单宏和可编程补全;rlwrap 自带 Perl 与 Python 模块,并在系统中安装了一批示例过滤器[2]。
发展历程
rlwrap 由 Hans Lub 编写,readline 库本身由 Chet Ramey 开发,承担了大部分底层工作。其伪终端处理代码几乎原封不动地取自 rxvt-2.7.10,补全词表则由 Damian Ivereigh 的 libredblack 库管理[4]。
该项目中 Hans Lub 的版权声明覆盖 2000 年至 2017 年,采用 GPL-2.0-or-later 许可证发布。文档随版本更新留下时间痕迹:一份手册对应 0.21 版,日期为 2004 年 1 月 30 日[5];另一份对应 0.37 版,日期为 2010 年 1 月 4 日[4];还有一份手册标注的日期为 2022 年 7 月 27 日[6]。
rlwrap 已被众多发行版和包管理器收录,包括 Alpine、Debian、Fedora、Homebrew、MacPorts、Nix、Arch、Ubuntu 与 openSUSE 等体系,项目宗旨是在新旧 Unix 类系统上保持可移植性,覆盖 Linux、macOS、FreeBSD、HP-UX、AIX、Solaris、QNX 和 Cygwin[7]。其上游最新版本为 0.48[8]。
应用
rlwrap 最典型的用途是给缺少行编辑的命令补上方向键历史与编辑能力,例如直接运行 rlwrap nc 即可让 netcat 获得命令行编辑和历史[2]。它同样适用于旧式交互式解释器、数据库客户端和网络工具,因为这些程序往往没有现代的输入编辑与持久历史[7]。
对于自身已经使用 readline 的命令,可以加上 -a 选项强制始终停留在 readline 模式,以取得 rlwrap 的历史和补全;此时若不给出命令的密码提示符作为参数,输入的口令会被回显并存入历史[2]。配合 -z pipeto 过滤器,可以让 SQL 命令的输出经由分页或筛选程序处理,并借助 -f 指定的词表对 SQL 关键字作不区分大小写的补全[2]。
补全词表可由 -f 选项从文件中读入,这一选项可以多次给出,与用户目录或系统中预置的默认补全表叠加;指定 -f 后跟一个点号,则以当前历史文件作为补全词表[2]。历史长度默认上限为 300 条,可用 -s 调整,负数表示仍按该数量保存但把历史文件视为只读[2]。此外还有 -m 多行输入、-N 避免包装命令所调用的编辑器与分页程序、-o 在接收第一行输入后向命令发送文件结束符等选项[9]。
在需要用户定义补全、持久历史,或要以过滤机制实现特殊效果时,rlwrap 尤其值得考虑[10]。
局限
rlwrap 无法得知目标命令的内部状态,因此不可能实现上下文相关的补全;在命令内部直接调用 readline 库仍然是更优的做法[11]。
直接模式与 readline 模式之间的切换依赖对伪终端状态的判断,可能不够可靠;在耐心模式下抑制提示符闪烁的同时,也会干扰较长的输出行,并使模式切换更不稳定[2]。提示符识别本身也是启发式的,命令输出被分块读写时,需要靠等待时间来区分普通末行和真正的提示符[2]。
对已经自带行编辑、长期处于原始模式的复杂命令,rlwrap 可能看起来什么也不做,必须借助 -a 才能生效;启用该选项又可能让命令调用的编辑器、分页程序无法正常接收按键[2]。此外,过滤器需要遵守特定的通信协议,sed、grep 之类普通 shell 命令不能直接充当过滤器,需经 makefilter 转换[2]。
参见
参考资料
- Package: rlwrap (0.47.1-0.1 and others) [引用日期2026-10-14]
- rlwrap(1) General Commands Manual rlwrap(1) [引用日期2026-10-14]
- rlwrap [引用日期2026-10-14]
- rlwrap.1.en [引用日期2026-10-14]
- man [引用日期2026-10-14]
- rlwrap - マニュアルページ セクション 1: ユーザーコマンド [引用日期2026-10-14]
- rlwrap [引用日期2026-10-14]
- Base Package: rlwrap [引用日期2026-10-14]
- rlwrap.1 [引用日期2026-10-14]
- Rlwrap - Free Software Directory [引用日期2026-10-14]
- rlwrap [引用日期2026-10-14]