Linux 下 rar/unrar 安装、分卷压缩与解压实战 上周帮同事处理一批内网数据搬家的活儿对方从 Windows 那边丢过来一个.rar包他随手敲了rar x xxx.rar终端直接回了一句command not found。他转头问我Linux 不是号称什么命令都有吗这个问题我这些年被问过不下十次每次都得从头解释一遍rar不是 Linux 世界里的原住民它是从 DOS/Windows 生态一路长过来、后来又单独移植到 Linux 上的工具绝大多数发行版默认不装装了之后rar和unrar还是两个不同的东西。而它最有价值的地方恰恰是tar、gzip、zip这些原生工具不太擅长的那几件事——跨平台交付、分卷、恢复记录、以及给完全不懂命令行的同事一个双击就能开的压缩包。这篇东西我打算按我自己的使用顺序来写先解决装不上的问题再讲压缩侧参数怎么选然后是解压侧最容易翻车的几个点中文乱码、覆盖策略、路径安全接着单独把密码和加密拎出来说最后落到能直接抄走的备份脚本和一份报错对照表。如果你平时只解压别人发来的包看完第 1、3 两节基本就够了如果你要在服务器上做定时归档第 2、6 节是重点。1. 敲下 rar 却提示 command not foundLinux 上 rar 的真实安装处境1.1 rar 和 unrar 是两个独立的二进制很多人以为装一个rar就什么都齐了其实不是。RARLAB 官方的 Linux 移植包解压出来是两个可执行文件rar和unrar。rar是全能选手既能打包a、也能解包x/e、还能改包d/u/m、加锁、加恢复记录。unrar是只读选手只有解压相关的子命令x、e、l、lt、p、t、v没有任何写操作。为什么拆开因为官方对这两个东西的授权态度不一样。unrar的源码是公开的允许自由分发和使用所以 Debian 把它放进了non-freeUbuntu 放进multiverse而rar的打包端属于商业授权软件官方提供的是试用版二进制企业环境长期跑归档任务时最好老老实实按需采购授权别拿试用版硬顶生产。这个区别带来一个很实际的后果你在一台干净服务器上想解压.rar理论上只需要unrar但你要主动生成.rar给别人就得把rar也装上。1.2 各发行版的安装路径差异对照我把自己踩过的几个平台整理成一张表省得你再去翻文档。发行版包名所在仓库备注Ubunturar、unrarmultiverse默认可能没启用 multiverseDebianrar、unrarnon-free需要在 sources.list 里加 non-freeFedora / RHEL / CentOS无官方包官方源没有只能从 RARLAB 官网下 tar.gzArch / Manjarorar、unrarAUR用 yay/paru 装openSUSErar、unrarPackman 源需要先加 PackmanAlpinerar、unrarcommunity部分版本只有unrarUbuntu 上装之前先确认仓库可见性apt-cache policy unrar rar如果输出里 Candidate 是(none)说明multiverse没开。Debian 同理检查/etc/apt/sources.list里有没有non-free新版是non-free non-free-firmware。这一步别跳过很多人后面装不上就开始乱找第三方源其实只是仓库没启用。Fedora、RHEL 这类系统上官方源确实没有。我的做法是去 RARLAB 官网的下载页拿对应架构的压缩包通常是rarlinux-x64-版本.tar.gz或rarlinux-arm-版本.tar.gztar -zxvf rarlinux-x64-6xx.tar.gz cd rar sudo install -m 0755 rar unrar /usr/local/bin/ sudo mkdir -p /usr/local/lib sudo cp rarfiles.lst /usr/local/lib/ 2/dev/null || true装完立刻验证别等到用的时候才发现 PATH 不对which rar unrar rar | head -5 # 看版本号和版权信息 unrar | head -3 # unrar 只输出版本行提示/usr/local/bin必须在$PATH里绝大多数发行版默认就在。如果which找不到先看echo $PATH别急着怀疑安装步骤。1.3 unrar-free 这个坑我劝你别踩有些发行版尤其 Debian 系仓库里有一个叫unrar-free的包它的定位是自由软件实现的 RAR 解压器。听起来很美好实际用起来很糟它只支持 RAR 2.0 左右的老格式遇到 RAR5 归档直接给你来一句unsupported method或者干脆解出来一堆 0 字节文件。更坑的是装了unrar-free之后/usr/bin/unrar可能被它接管你以为自己在用官方版实际上一直在用它。判断方法很简单unrar | head -3官方版会明确打印UNRAR 6.xx freeware之类的字样unrar-free的输出格式完全不同而且没有版本号那一行。发现装错了就卸干净再重装别指望它哪天突然支持 RAR5。2. 压缩侧参数体系-m、-v、-r 背后的取舍逻辑2.1 压缩级别从 -m0 到 -m5不是越高越好rar的压缩级别一共六档从-m0到-m5。这块我见过太多人无脑上-m5然后抱怨备份任务跑了四个小时还没结束。级别含义适用场景相对耗时-m0仅存储不压缩jpg、mp4、gz、qcow2、已压缩包最快-m1最快压缩临时归档、速度优先很快-m2快速压缩日常通用快-m3标准压缩默认值备份场景首选中等-m4较好压缩文本、日志、源码慢-m5最大压缩归档后基本不再动追求极限体积最慢关键判断依据是数据本身的熵。日志、源码、纯文本、CSV 这类冗余度高的内容-m5相比-m3能再挤出 5% 到 15% 的体积值得而.jpg、.mp4、.qcow2、.tar.gz这些已经是压缩格式的文件再压一遍几乎是纯浪费时间收益常在 1% 以内。我之前给一批虚拟机镜像做归档用-m5跑了一晚上结果体积只比-m0小了 0.7%从此这类数据我一律-m0。还有两个和压缩率相关的开关值得记住-ssolid固实压缩把多个小文件当成一个连续数据流来压。几百上千个小文件时体积改善非常明显通常能到 20% 以上。代价是解压单个文件时必须先把前面的数据流都跑一遍随机读取变慢。-s-关闭固实。当你的归档需要频繁按需抽取个别文件时用它。RAR5 格式默认是固实的所以如果你发现只想拿一个配置文件却等了十秒原因就在这儿。2.2 通配符和递归顺序决定了归档里长什么样rar a的目标名如果不带后缀它会自动补.rar。真正容易出问题的是文件列表部分。规矩是这样的你直接给一个目录名比如rar a bak.rar /data/app它会把该目录连同所有子目录一起收进去你用通配符比如rar a bak.rar *.log默认只在当前层匹配不会往子目录钻。想递归就得显式加-rrar a -r bak.rar *.log注意通配符一定要加引号否则会被 shell 抢先展开成具体文件名如果当前目录恰好一个.log都没有shell 会把*.log原样传给rar它又匹配不到最后你得到一句轻飘飘的No files added。路径处理有三个常用参数选错会让归档里多出一串莫名其妙的目录-ep不保存任何路径所有文件都平铺在归档根目录。适合我只要文件不管层级。-ep1去掉命令行里指定的那个基目录但保留它下面的子目录结构。这是做归档最常用的一个cd /data/app rar a -r -ep1 bak.rar logs得到的就是logs/xxx的结构。不加任何 ep 参数按你给的路径原样保存。给了绝对路径归档里就会出现完整路径链换台机器解压时容易懵。我自己固定用-ep1理由是归档解压出来应该是一个干净的目录而不是把服务器的目录结构整个复印一遍。2.3 分卷压缩 -v 的切片策略与还原前提-v是rar相对tar/zip最实用的能力之一。用法rar a -v100m bak.rar /data/app # 每卷 100MB rar a -v2g -m3 -ep1 big.rar ./data # 每卷 2GB支持的单位有k、m、g还有b字节。RAR5 格式下分卷名是bak.part1.rar、bak.part2.rar这样老一些的 RAR4 格式是bak.rar、bak.r00、bak.r01。想强制用哪种命名可以加-vn走旧式命名。分卷的使用有几个硬性前提破了任意一条都会失败所有卷必须在同一个目录里。少一个卷unrar会报You need to start extraction from a previous volume或者Cannot open bak.part3.rar。解压只对第一卷操作。不要想着单独解part5它是数据流中间的一段脱离上下文没有意义。不要重命名卷。part1、part2的顺序编号是唯一的定位依据改名就断了。传输过程要保证完整性尤其是走邮件、网盘的时候。中小体积的分卷建议配合-rr5p加 5% 的恢复记录rar a -v200m -rr5p bak.rar /data/app恢复记录的作用是当某个卷出现少量损坏时unrar能靠冗余数据把坏块修回来。我做过一个不太严谨的对照给一批 100MB 的包人为改坏几个字节不带恢复记录的包直接报Checksum error解不出来带-rr5p的能正常还原。这个参数在跨地域传文件时几乎是必加项。3. 解压侧实战x 与 e 的抉择、中文乱码与覆盖行为3.1 x 和 e 的差别决定了解压后目录乱不乱unrar最常用的两个解压命令是x和e差别只有一个字面路径。unrar x按归档里记录的路径解压会创建对应的目录树。默认选它。unrar e把所有文件平铺到目标目录路径全部丢掉。e的危险在于归档里a/conf/app.yml和b/conf/app.yml两个文件会互相覆盖最后只剩一个而且没有任何提示。我只有一种情况会用e确认归档里全是同一类平铺的散文件比如一堆扫描件。unrar x -o package.rar ./out/ unrar e -o flatfiles.rar ./out/指定解压目录的写法是把目标路径放在最后而且结尾的斜杠最好别省否则在某些版本上会被当成归档内的路径名去匹配文件结果是解出来一个空目录。想先看清楚包里有什么再动手用三个不同的列表命令命令输出内容什么时候用unrar l详细列表含大小、时间、CRC日常查看最常用unrar lb只列文件名喂给脚本做判断unrar lt技术信息含压缩方法、加密状态排查为什么解不开unrar t只测试不写出文件批量验证归档完整性unrar t这个我强烈建议在正式解压前跑一次尤其是从外部拿到的包。它会完整读一遍数据流并校验 CRC能提前把损坏的包揪出来避免你解到一半失败还得清理现场。3.2 中文乱码的成因和三条处理路径这是.rar在 Linux 上被吐槽最多的一个问题没有之一。现象是解压出来的文件名变成一堆问号或者拉丁字母乱码。成因其实很清楚Windows 上打包时文件名在归档里以本地代码页通常是 GBK/CP936的字节形式存储到了 Linux 这边终端和文件系统按 UTF-8 去解释这串字节自然就对不上。严格说文件内容没问题坏的是名字。处理路径有三条按可靠性排序第一条用unar。这是 The Unarchiver 的命令行版本可以直接指定编码unar -e GBK package.rar它把归档里的文件名按 GBK 解码后重新用 UTF-8 写出去一次到位。这是我现在的首选能装就装。第二条先解压再用convmv批量改名。适用于已经解压出来一堆乱码名的情况convmv -f GBK -t UTF-8 -r --notest ./target_dir-r递归--notest是真正执行不加这个只是试跑输出会告诉你打算改什么这个预览功能挺有用第一次用建议先不带--notest看一眼。第三条用7z x或bsdtar试试。新版 p7zip/7zz 对归档里的编码标记处理得比unrar好一些有时候同一个包unrar出来是乱码、7z出来就正常。顺手提一句7z解.7z、.tar.xz、.zip也都能干服务器上装一个不亏。注意网上有些老帖子说加-e19之类的参数能解决乱码。这个参数在不同版本的unrar上行为不一致新版本上直接报Unknown option别把它当银弹。先用unrar lb看一眼列表确认是不是乱码再决定用哪条路径。3.3 -o、-o-、-or脚本里必须显式指定覆盖策略unrar遇到同名文件时默认会交互式询问。这在终端里没问题但放到 cron 或者 CI 里就是灾难——进程会挂在那里等输入直到超时被杀死你从日志里只看得到任务没跑完。三个覆盖策略脚本里必须选一个-o无条件覆盖。-o-跳过已存在的文件。-or自动重命名比如app.yml存在就存成app_1.yml。我一般这样做正常解压用-o因为目标目录通常是新建的批量增量更新用-o-做对比分析时用-or保留所有版本。配套的还有-y把所有交互式提问都当成是。在完全无人值守的脚本里-o -y基本是标配。另外如果归档带密码脚本里不要让它弹提示加-p-让它直接报错失败这样日志里能明确看到缺密码而不是卡住。3.4 只解压需要的部分-n 和 -x 的组合归档里几十万个文件你只想要几个配置全解开纯属浪费。-ninclude和-xexclude能精确控制unrar x -n*.conf -n*.yaml big.rar ./out/ # 只要这两类 unrar x -x*.log -x*.tmp big.rar ./out/ # 排除这两类 unrar x -nconfig/* big.rar ./out/ # 只要 config 目录下的注意模式匹配是大小写敏感的而且-n可以和-x同时用逻辑是先按-n圈定范围再按-x剔除。列表很长的时候可以写成文件用-nlistfile读进来。解压单个文件更直接unrar x big.rar path/inside/file.conf ./out/这里有个容易忽略的点unrar匹配的是归档内的完整路径你得先用unrar lb | grep file.conf确认具体路径抄错一层就匹配不到最后得到一个空目录加一行No files to extract。4. 密码、加密与文件头保护-p 和 -hp 差在哪4.1 -p 加密的是内容-hp 加密的是全部这两个参数经常被混用但安全级别差着一个数量级。-p密码加密文件数据。归档的文件列表、文件名、大小、修改时间这些头部信息不加密任何拿到包的人不用密码就能unrar l看到里面有什么文件。-hp密码加密数据加上文件头。没有密码连unrar l都列不出来会直接要求输入密码。打包时的写法rar a -p$PWD_STR normal.rar ./data # 只加密内容 rar a -hp$PWD_STR secure.rar ./data # 内容和文件头都加密解压时-p和-hp都用同一个参数指定密码因为此时是解密不区分unrar x -p$PWD_STR secure.rar ./out/什么时候必须用-hp我的判断标准是文件名本身就构成敏感信息的时候。比如归档里是一批以员工姓名、客户编号、合同号命名的文件那文件名列表泄露的危害可能不比内容小。这时候-p形同虚设。4.2 加密带来的性能代价和密码传递的正确姿势rar用的是 AES-256加密是在压缩之后做的所以压缩率不受影响只多一层加解密开销。实测在常规服务器 CPU 上加密带来的额外耗时基本在 2% 到 5% 之间可以忽略。真正需要注意的是密码怎么传进命令。写成rar a -pmypassword ...是最糟的做法原因有两个它会被记进 shell 历史。在命令执行期间同机器上其他人ps aux就能看到完整命令行。正确的做法是从受保护的文件里读PW$(cat /etc/backup/rar.pwd) rar a -hp$PW -m3 -ep1 secure.rar ./data unset PW/etc/backup/rar.pwd的权限设成600属主是执行任务的账号。如果你用的是 systemd timer 而不是 cron还可以把密码放进EnvironmentFile指向的文件里效果类似。另外临时在终端里敲带密码的命令可以在命令前加一个空格前提是HISTCONTROL包含ignorespace这样不会进历史。还有一点-p后面跟密码时等号和引号的处理在不同版本上略有差异密码里如果含空格、$、!这类字符务必用双引号包起来否则会被 shell 先解释一遍。我有一次密码里带$结果rar收到的是被替换过的空值归档建出来没加密排查了半天才发现。4.3 密码丢了之后现实是什么样的这块我说点实话。RAR 的 AES-256 加密没有后门官方也没提供任何恢复途径。所谓一键移除 RAR 密码的工具绝大多数只对两种情况有效一是归档其实根本没加密只是被误认为加密二是老式 ZIP 的传统加密那种算法有已知弱点。对真正的 RAR AES 加密唯一的技术路径是密码枚举成功率完全取决于密码本身有多弱。所以我的建议很直接别把唯一一份数据的密码和归档存在一起也别指望事后能救回来。生产环境的做法是密码托管在独立的密码管理系统里归档任务定期做一次用托管密码试解压的演练验证密码和归档还配得上。这个演练看着多余但真出事的时候能救命——我见过不止一次密码记在运维同事的个人笔记里人离职了的情况。如果你是接收方拿到一个带密码的包但对方给错了密码unrar的报错通常是Checksum error in the encrypted file或者Wrong password。注意区分前者也可能是归档损坏配合unrar t能排除。5. rar、tar、zip、7z 该怎么选5.1 四个工具的能力对照这张表我整理过很多次放在这儿当速查。维度tar gzip/xz/zstdzip7zrar压缩率中到高中高高速度快zstd 极快快慢吃内存中Linux 原生支持内置基本内置需装 p7zip/7zz需额外安装Windows 同事友好度差极好中需装 7-Zip好保留 Unix 权限/属主好一般部分一般分卷需 split 配合支持但较弱支持完善恢复记录无无无-rr加密需配合 gpg传统加密偏弱AES-256AES-256流式处理支持管道不支持不支持不支持许可自由自由自由打包端商业授权几个要点展开说tar 严格来讲只是打包不压缩。.tar.gz是 tar 负责把一堆文件串成一个流gzip 负责压。这个分工带来一个巨大优势可以走管道tar -cf - /data | ssh host tar -xf - -C /backup这种边打包边传输的玩法rar 和 zip 都做不到因为它们需要在输出端随机寻址写文件头。所以服务器之间搬数据我还是优先 tar zstd。tar 保留权限和属主是最可靠的。tar -xzf加上-p能把权限位、属主、软链接、硬链接、扩展属性都还原。rar 在这块弱不少跨系统搬运时经常需要事后手动chmod/chown。rar 有一个-ow开关可以在解压时恢复属主但需要 root 权限而且只对归档里确实记录了属主信息的情况有效软链接要用-ol才会按链接保存而不是跟随。zip 的优势只有兼容性。任何系统双击就能开这是它到今天还活着的原因。但它的传统加密ZipCrypto在密码学上早就不可靠而且 4GB 单文件限制虽然被 zip64 解决了各家实现的兼容性参差。7z 的压缩率确实好但代价是内存。用高等级参数压几十 GB 的数据内存占用能轻松上到几 GB在小内存 VPS 上直接 OOM。它适合本地一次性归档不适合做服务器定时任务。5.2 什么场景我仍然会选 rar综合下来这几种情况我还是会用 rar交付给 Windows 用户对方不装任何额外软件就能双击打开比 tar.gz 强太多。需要分卷传输尤其是走邮件附件或者有单文件大小限制的网盘时-v加-rr5p的组合最省心。需要恢复记录。这是 rar 的独门能力长期冷备的归档加 3% 到 5% 的恢复记录能在磁盘出现坏道时多一份保险。归档里有大量小文件固实压缩能省下可观的体积。反过来服务器间定期同步、需要保留权限、需要流式处理、磁盘空间紧张的场景我一律用 tar 系列。顺手说一个常见误区有人拿 rar 去压.qcow2虚拟机镜像或者.tar.gz备份包然后抱怨压缩率怎么才 1%。这不是工具的问题这些格式本身就是高熵数据再压没有意义用-m0直接存储就好省下的时间比那 1% 的空间值钱得多。同理.jpg、.mp4、.png、.zip都一样。6. 落地到脚本批量归档、定时任务与报错对照6.1 一个可以直接改路径用的日志归档脚本下面这个脚本是我在几台机器上跑了两年多的版本去掉业务相关的部分基本就是这个骨架。核心思路是进到源目录的上级用-ep1剥掉基目录归档到独立分区打包后立刻校验最后按天数清理。#!/bin/bash set -euo pipefail SRC_PARENT/data/app # 源目录的上级 BASE_NAMElogs # 要归档的目录名 DST_DIR/backup/rar # 归档落地目录 STAMP$(date %Y%m%d_%H%M) KEEP_DAYS7 LOG_FILE/var/log/rar_backup.log RAR_BIN/usr/local/bin/rar mkdir -p $DST_DIR log() { printf [%s] %s\n $(date %F %T) $* $LOG_FILE; } ARCHIVE$DST_DIR/${BASE_NAME}_${STAMP}.rar cd $SRC_PARENT if $RAR_BIN a -m3 -r -ep1 -idq -o -t \ -v2g -rr5p \ $ARCHIVE $BASE_NAME; then log OK $ARCHIVE else log FAIL $ARCHIVE exit 1 fi find $DST_DIR -maxdepth 1 -name ${BASE_NAME}_*.rar \ -mtime $KEEP_DAYS -print -delete $LOG_FILE log cleanup done, keep ${KEEP_DAYS} days逐条说下参数为什么这么选-m3日志是文本冗余度高-m3到-m4之间的收益已经不明显而-m3的速度快一截日常任务用它是性价比拐点。-r -ep1递归收集子目录同时把logs/这层基目录从归档里剥掉解压出来就是一个干净的目录内容。-idq只输出错误避免每天往日志里灌几千行进度。排查问题的时候可以临时把它去掉。-o同一天重跑任务时直接覆盖避免因为文件已存在而卡在交互提示上。-t打包完成后立刻做一次完整性校验。这一步很多人省掉结果归档写了一半磁盘满了直到几个月后要恢复时才发现包是坏的。-v2g -rr5p单卷 2GB配合 5% 恢复记录方便走各种传输通道也留了出错冗余。find ... -delete清理旧卷。注意分卷会产生logs_20240101_0300.part1.rar、part2这种名字-name ${BASE_NAME}_*.rar这个模式能匹配到它们。6.2 大目录怎么处理才不会被 OOM 或者句柄数搞死归档一个几十万文件的目录时有两个资源瓶颈文件描述符。rar在处理海量小文件时会频繁开关文件句柄如果目录层级特别深可能触发ulimit -n的限制。先看一眼当前值必要时在脚本里临时抬高ulimit -n 65535内存。-m5配合固实压缩时rar会维护一个比较大的字典文件特别多时内存占用会上去。如果机器内存吃紧降到-m2或者加-s-关掉固实能明显缓解。还有一个实践上的做法按子目录分批归档每个批次一个独立包。for d in /data/app/*/; do name$(basename $d) rar a -m3 -ep1 -idq $DST_DIR/${name}_${STAMP}.rar $d || true done这样做的好处是单个包出问题不影响其他包恢复时也只需要处理相关的那一个。缺点是放弃了跨目录的固实压缩收益。文件数量超过十万的时候我基本都选分批。6.3 cron 里跑 rar 的几个隐形坑PATH 问题。cron 的PATH通常只有/usr/bin:/bin如果你把rar装在/usr/local/bin直接写rar a ...会报command not found。解决办法是在脚本里用绝对路径我上面就是这么写的或者在 crontab 开头显式设PATH。LANG 问题。cron 环境下的LANG往往是空的rar输出里的中文路径可能变成问号甚至影响文件名的处理。稳妥做法是在脚本开头设export LANGen_US.UTF-8避免编码随环境漂移。并发问题。同一个归档文件绝对不能让两个进程同时写rar不会做跨进程加锁结果是包损坏。如果任务可能超时未完成而下一个周期又启动了用flock加个锁exec 9/var/lock/rar_backup.lock flock -n 9 || { echo previous run still active; exit 0; }空间问题。归档目录最好在独立分区并且提前估算。压缩前的体积可以粗略用du -sh拿到压缩后大概按 20% 到 40% 估文本类已压缩数据按 100% 估因为-m0基本不缩。6.4 常见报错与处理对照最后这张表是我这些年攒下来的遇到报错先来这儿找。报错信息大概率原因处理办法rar: command not found未安装或不在 PATH装包或检查$PATHCannot open xxx.rar路径含空格/权限不足/磁盘满加引号检查目录写权限和空间No files added通配符没匹配到任何文件确认路径和模式通配符加引号Checksum error归档损坏或密码错误先用unrar t确认带-rr的可用恢复记录Wrong password密码不对确认密码注意 shell 特殊字符转义You need to start extraction from a previous volume分卷不齐确认part1到partN全在且未被改名unsupported method用了unrar-free换成官方unrar解压后文件名乱码归档里是 GBK 文件名用unar -e GBK或convmv改名Permission denied解压时目标目录不可写换目录或调整权限进程卡住不动在等覆盖确认或密码输入加-o -y、-p-我个人在实际操作中的体会是rar在 Linux 上真正让人头疼的从来不是参数本身而是它不在默认环境里和它的文件名编码跟 Linux 语境对不上这两件事。把安装路径固定下来、把乱码处理的习惯动作练熟、把脚本里的覆盖策略和解压目录写死剩下的就是常规的调参了。另外再分享一个小技巧新建归档之后别只看命令有没有报错随手跑一遍unrar t和unrar l | head -20确认里面装的东西和路径结构都符合预期——这个习惯帮我拦下过好几次目录层级多了一层和归档其实是空的的低级失误成本只要两秒。