首页 / 资讯中心 / 文章详情

Linux unrar 解压 RAR 实战:安装、命令与批量自动化避坑

Linux unrar 解压 RAR 实战:安装、命令与批量自动化避坑 ★ FEATURED ARTICLE
1. 为什么 Linux 上解压 RAR 还得专门请 unrar 出场第一次在服务器上接手一个.rar包的人大概都有过这个瞬间unzip报错说不认识这个格式tar更不可能转头去查才发现要装一个叫unrar的东西。这个工具的定位其实非常窄——它不打包、不压缩、不支持别的格式它唯一的工作就是把RAR 压缩包解压出来顺便把包里的内容列给你看、校验一遍完整性。窄归窄但它在现实里的出场频率相当高Windows 上做设计稿交付的、Git 上放资源包的、老系统里做数据归档的、某些硬件厂商随驱动光盘给的资料包一大半都是.rar。后面我会按实操顺序讲清楚三件事怎么装、怎么用、出问题怎么查。装的部分会说明两个版本的差别以及无网络环境的处理用的部分会把x、e、l、t这四个高频命令拆开把覆盖策略、选择性解压、密码、分卷这些参数讲到能直接抄查的部分集中处理中文文件名乱码、路径穿越、压缩炸弹、权限错乱这几类我在实际环境里反复遇到的坑。适合刚接手 Linux 服务器、需要处理批量压缩包交付的读者也适合已经在用但想把这些参数彻底摸清的老手。补一句范围说明下面提到的发行版分类、参数、返回码都以官方 unrar 的行为为准不同小版本之间会有细微差异具体以你机器上unrar的帮助输出为准。2. 动手之前先想清楚格式封闭性决定了工具选型2.1 RAR 的特殊性决定了它没有系统自带这条路.zip在 Linux 上能用unzip.tar.gz能用tar是因为它们的实现早就有开放的标准可循几乎所有发行版都会顺手带上。RAR 不一样它的压缩算法和容器格式由一方维护只对外提供免费的二进制解压器代码本身不公开。这个现实直接导致两个结果——一是没有任何主流发行版会把 unrar 塞进默认镜像里你必须在装系统之后手动补一次二是你拿到的永远是一个能解不能压的工具想生成.rar需要另外一方的打包工具那是另一件事。我见过不少人吐槽Linux 连个 rar 都解不了太寒酸了其实这是误解。不是解不了是默认不预装。装完之后解压速度、兼容性一点不差甚至比某些第三方实现更稳因为它和格式是同一套实现出来的。另外一个容易被忽略的点RAR 格式本身还在演进。早期的 RAR 和后来的 RAR5 在容器结构上有差别一些第三方解压器对 RAR5 的支持是打折扣的尤其遇到加密头、多卷、恢复记录这些高级特性时会直接放弃。所以在我该用哪个工具这个问题上不能只看能不能打开要看能不能完整打开。2.2 三条路线怎么选官方 unrar、7z、unar实际环境中你至少有三种选择各自的强项差别挺大我给一张表方便对照工具RAR5 支持文件名编码处理速度适合的场景官方 unrar完整默认按系统 locale新版可指定字符集快单核跑满日常解压、批量脚本、分卷、加密包7z / p7zip较好但个别高级特性可能缺失可通过代码页参数指定中等混合格式环境、包里还含 7z/zip 时统一用一套命令unar一般对旧编码文件名兼容性好偏慢只关心文件名不乱码、能出文件就行我的默认选择是官方 unrar原因很实在它对自己的格式不会有兼容性意外。碰到解压到一半报 CRC 错误、或者分卷找不到后续卷的情况官方实现给出的错误信息更准确排查方向更清楚。7z 的优势在于一个命令吃多种格式如果你的环境里同时有 rar、7z、zip用 7z 能少装几个工具少维护几套脚本。unar 我一般只在一种情况下用对方在很老的 Windows 环境下打包文件名是 GBK而我又不想事后改名。它的编码识别策略更宽容一些。但只要不是这种情况我仍然回到 unrar。2.3 两个版本源的差别别装错了这个名字下有两个东西容易混一个是官方版本只以二进制形式分发功能完整是新格式、新特性的第一落点另一个是独立实现的 unrar-free早年作为替代品出现但它对后来的格式版本支持非常有限遇到 RAR5 的包大概率直接失败还可能把带密码的包当成损坏包报错。判断方法很简单装完跑一次unrar不带参数看输出头部的版本号和版权说明。如果版本号停留在很低的数字、帮助里没有-sc之类的参数那很可能是 free 版。我踩过一次坑在一台老机器上按习惯装了包批量脚本跑了半小时一个包都没解开日志里全是格式不支持最后发现版本号对不上。从那以后我在所有自动化脚本里都加了一行启动自检见第 3 节。3. 安装与版本基线确认3.1 各发行版系的安装路径不同家族的命令有差别我把常用的整理成一张表注意包名差异发行版系安装命令备注Debian / Ubuntu 系sudo apt update sudo apt install unrar需要先启用包含该包的软件源若只装到 free 版用apt policy unrar确认Red Hat / CentOS / Fedora 系sudo dnf install unrar部分版本需先启用额外软件源rpm -qa | grep unrar复核Arch 系sudo pacman -S unrar仓库里就是官方版最省心Alpinesudo apk add unrar容器镜像里常用注意镜像本身是 musl容器场景要提醒一句Alpine 基础镜像里没有 glibc如果你直接拷一个编译好的二进制进去可能因为动态链接库缺失跑不起来。稳妥做法是用包管理器装或者用静态编译的包。我在一个精简镜像里图省事直接COPY二进制运行时提示找不到解释器折腾了半天才反应过来是库依赖问题。装完之后建议顺手确认一下二进制路径command -v unrar。有些环境里同时存在多个版本PATH顺序会影响实际调用的是哪一个这在排查为什么命令行为和我预期不一样时非常关键。3.2 没有外网时怎么落地内网服务器、离线环境是常态。这时候有两条路第一条是从能上网的机器上下载对应的压缩包或二进制文件拷进去手动放置。注意要挑和系统架构、库版本匹配的那一个uname -m先确认是 x86_64 还是 aarch64。放好之后sudo install -m 755 unrar /usr/local/bin/unrar unrar | head -n 3install比cp好在一步到位设好权限省得后面忘了chmod导致命令找不到或者没权限执行。第二条是走内部镜像源。很多团队会维护一个内部软件源把官方包镜像进去这样新机器一条命令就能装好也不用担心版本漂移。这件事看似麻烦但在机器数量超过五台之后收益非常明显——我见过因为不同机器 unrar 版本不一致同一个包在 A 机器能解、B 机器报错的排查现场最后发现纯粹是版本差异。注意不要把解压工具和业务镜像绑死在一个层里却不记录版本。至少在一个说明文档里写清楚当前基线版本出问题时才有对照物。3.3 装完先做一次能力自检我的习惯是每次部署完就跑一组自检确认这个二进制确实能干完整的活unrar # 看版本号与可用命令 unrar 21 | grep -i unrar | head -n 1 command -v unrar unrar | grep -i \-sc || echo no charset switch最后一行是在探测是否支持字符集指定这个参数在处理中文乱码时很有用。如果探测不到说明版本偏老后面处理乱码就得换思路见第 5 节。再补一个更彻底的验证拿一个已知内容的小 rar 包跑完整流程——t测试、l列表、x解压、比对文件大小和数量。这一步花不了两分钟但能省掉后面半小时的困惑。自动化脚本里我也常把这段写成启动检查一旦不通过就立刻退出避免它默默跑完却什么都没解出来。4. 核心命令拆解x、e、l、t 四把刷子4.1x和e路径策略决定了后面所有事这是最容易用错、也最容易后悔的一个选择。unrar x archive.rar会保留压缩包内的目录结构文件按原来的层级落盘。unrar e archive.rar则是把所有文件平铺到当前目录路径信息全部丢掉。为什么这件事重要因为很多 RAR 包内部是有层级的比如design/2019/a.png、design/2020/a.png。用e解压两个a.png会撞在一起而默认的覆盖策略是询问——在交互终端里它会停下来等你回答在脚本里没接标准输入它可能直接跳过或报错结果就是文件缺失且没有明显提示。我第一次踩这个坑是在一个批处理任务里跑完之后发现文件数少了一半日志里只有一行不起眼的提示找了很久才定位到是重名覆盖。所以规则很简单只要包里可能有同名文件一律用x。只有明确知道包内是扁平结构、或者你就是想把所有文件抽出来放一起时才用e。指定目标目录时把路径放在最后mkdir -p /data/extract/app01 unrar x -o archive.rar /data/extract/app01/目标目录必须先存在unrar 不会替你创建顶层目录。这一条踩过的人不少报错信息也不够直白容易以为是权限问题。如果想让每个包解到以包名命名的子目录里有个很省事的参数unrar x -ad archive.rar /data/extract/-ad会把压缩包文件名追加到目标路径后面自动形成/data/extract/archive/。批量处理时这个参数能省掉一大段循环里拼目录名的代码。4.2l和t动手之前先看清楚unrar l archive.rar是列表输出每一行的文件名、原始大小、修改时间、属性、CRC。unrar lt是技术列表格式更规整适合用awk处理unrar lb只输出裸文件名一行一个最适合喂给grep。三个参数组合起来能干一件很有价值的事在解压前做安全检查。比如检查包里有没有试图跳出目标目录的路径unrar lb archive.rar | grep -E (^|/)\.\.(/|$) echo 发现可疑路径拒绝解压t是测试命令它会把包内数据完整读一遍并校验 CRC但不写盘unrar t -inul archive.rar echo exit$?-inul关掉所有输出只看返回码。这个组合在我的自动化流程里是标配先t后x。原因很实际——如果包本身在传输过程中损坏了直接x会解出半截文件而半截文件比没有文件更麻烦下游程序可能把它当正常输入处理错误会传播得很远。先花几秒测一遍能挡掉绝大部分问题。lt的输出还能帮你估算磁盘空间。注意看列表末尾的总大小那一行那是解压后的总字节数用它和df -h的可用空间对比比解压到一半失败然后清理残局要优雅得多。4.3 覆盖策略-o、-o-、-or怎么挑默认行为是遇到同名就问你在交互场景下很友好在脚本里是灾难。三个参数解决这个问题-o无条件覆盖。适合目标目录是干净新目录的场景或者你明确希望用新版本替换旧文件。-o-跳过已存在的文件不覆盖。适合增量更新比如每天同步一次的素材包。-or自动重命名把冲突文件改成file_1.png这种形式。适合归档场景宁可多留一份也不丢数据。选择逻辑其实就是问自己一句这次解压是重建还是补充。重建就用-o补充就用-o-。归档合并这种既不想丢又不想覆盖的才用-or。还有一个参数值得记住-y。它对所有询问一律回答是。有人图省事直接-y配默认覆盖策略等于隐式打开了-o在目标目录里有重要文件时会出问题。我的建议是显式写覆盖策略不要靠-y兜底这样命令读起来意图清楚别人接手也不会误解。4.4 选择性解压、密码与分卷包里只有几个文件需要没必要全解unrar x archive.rar *.pdf docs/*.md /data/extract/app01/只解 PDF 和 docs 下的 md。配合排除unrar x -x*.tmp -x__MACOSX/* archive.rar /data/extract/app01/后一个排除特别实用。在非 Windows 系统上打开过的包经常混进一堆以点开头或下划线开头的垃圾目录和资源文件解出来既占地方又干扰后续处理提前排掉省事。带密码的包密码写在参数里unrar x -pYourPass archive.rar /data/extract/app01/注意密码里如果有特殊字符单引号包起来最稳。另外有个细节值得提如果包使用了加密头连文件名都加密那么不带密码时l命令连列表都出不来会提示输入密码。这时候可以用-p-明确表示没有密码不要问我让它在无密码时直接失败退出而不是卡在交互上等输入。这在脚本里非常关键——任何可能触发交互提示的命令在自动化里都要显式关掉询问。分卷包的处理比想象中简单指向第一卷就行后续卷会自动找。unrar x archive.part1.rar /data/extract/app01/前提是所有分卷都在同一目录、命名连续。如果中间缺了一卷会报找不到下一卷这时候用ls -1 archive.part*.rar排一下序检查编号有没有断档。我遇到过一次是下载工具把第 5 卷存成了part05而其他是part5肉眼扫一眼看不出来排序之后立刻暴露。5. 易错点实录乱码、穿越、权限5.1 Windows 打包的中文文件名乱码这大概是被问得最多的问题。现象很统一解压出来的文件名全是问号、方块或者变成?®???这种看不懂的组合文件本身内容是好的。原因是编码对不上。对方在 Windows 上打包时文件名大概率按 GBK 那套编码写进包里Linux 这边的文件名按 UTF-8 处理字节序列一解释就错位了。这不是 unrar 的 bug是两边对字节代表什么字符的约定不同。处理有三条路我按推荐顺序排第一条用新版 unrar 的字符集参数在解压时直接指定unrar x -scgbk archive.rar /data/extract/app01/具体可用的字符集标识以unrar帮助里的说明为准不同版本命名可能略有差异。这条路最干净一步到位不用二次改名。第二条先解压再批量改名。用convmv把目录里所有文件名从 GBK 转成 UTF-8convmv -f gbk -t utf-8 -r --notest /data/extract/app01/--notest是真正执行不加它只是演练。我建议第一次先不加看它打算改哪些确认没问题再执行。这条路的好处是不依赖 unrar 版本缺点是如果文件名里混了多种编码一刀切会改坏一部分。第三条换工具。7z 可以通过代码页参数指定unar 对旧编码的识别更宽容。这条路我一般放在最后因为引入新工具意味着脚本里多一个依赖。注意不要在解压之后用mv手工一个个改。文件名数量一多必然出错而且改错之后原始名字就丢了没法回滚。5.2 路径穿越与解压炸弹这两个是安全层面的问题值得单独说。路径穿越包内条目如果写成../../etc/something解压程序按字面拼路径文件就可能落到目标目录之外。正规实现通常会做检查并跳过但不能完全指望它——尤其是你把解压放在高权限用户下跑的时候。我的做法是在解压前做一次检查就是 4.2 节那行grep把带..的条目揪出来。宁可误判拒绝也不要赌一次。更稳的是隔离解压永远用一个专用的低权限用户目标目录永远在一个受控的父目录下。这样即使真出了问题影响范围也被框住了。解压炸弹一个小压缩包解压出几十 GB 数据把磁盘塞满进而影响同机器上的其他服务。防护思路是先看大小再动手unrar lt -inul archive.rar | tail -n 3 df -h /data用解压后总大小和目标盘可用空间做对比设一个阈值超过就拒绝。这个检查写进脚本只需要两行但能防住一整类事故。还有一个变种是海量小文件几百 MB 的包解出几十万个文件inode被打满。这种情况看总大小看不出异常得看文件数量。unrar l -inul archive.rar | wc -l能大致估个数量级和df -i对照。5.3 权限、属主与 umaskunrar 解出来的文件权限取决于当前 shell 的umask和包里记录的属性。默认情况下新文件是644、目录是755这个结果在大多数场景下是对的。但如果包里带可执行文件或者你在做需要特定属主的部署就得注意。最常见的问题是用 root 解压文件属主全变成 root下游以普通用户跑的服务读不了。解决办法不是解压完再chown -R大目录会跑很久而是在解压时就指定用户sudo -u appuser unrar x -o archive.rar /data/extract/app01/另一个细节是权限继承。想控制解压出来的权限临时改umask比事后chmod -R快得多(umask 022; unrar x -o archive.rar /data/extract/app01/)括号包起来是为了让umask只在这个子 shell 里生效不影响当前会话。这个小技巧我在很多临时改环境变量的场景里都用比export之后再改回来安全。6. 批量化与自动化落地6.1 一批压缩包解到各自子目录需求很典型一个目录下几十个 rar每个解压到以自己名字命名的子目录。用-ad加一个循环就够#!/usr/bin/env bash set -euo pipefail SRC/data/incoming DST/data/extracted find $SRC -maxdepth 1 -type f -name *.rar -print0 | while IFS read -r -d pkg; do echo [*] $pkg unrar t -inul -- $pkg || { echo [!] 包校验失败跳过; continue; } unrar x -o -idq -ad -- $pkg $DST/ || echo [!] 解压返回非零 done几处细节值得说明-print0配IFS read -r -d 是为了应付文件名里的空格和特殊字符。用for f in *.rar在文件名带空格时会直接裂开这个坑几乎人人踩过一次。--是告诉 unrar后面不再解析成选项防止文件名本身以短横线开头时被误认成参数。这类文件不常见但一旦出现排查起来很费时间。-idq只显示错误让日志干净。真要详细排查时换成-idv。|| continue和|| echo的位置是有意安排的校验失败直接跳过这个包解压失败只记录不中断整批。批量任务的原则是单个失败不能拖垮全局但每一次失败都必须在日志里留痕。6.2 用返回码做精确判断只看命令有没有报错不够最好直接看返回码。常用的几个返回码含义处理建议0成功继续1有警告如部分文件损坏检查解出的文件数量是否完整2致命错误终止检查包完整性3CRC 校验错误包损坏重新获取4加密包需要提供密码5写错误检查磁盘空间与目录权限6打开文件错误检查路径、权限、是否存在7命令行错误检查参数拼写10没有匹配的文件检查筛选条件脚本里可以这样用unrar x -o -inul -- $pkg $DST/ 2/dev/null rc$? case $rc in 0) echo ok ;; 3) echo crc 错误$pkg /var/log/unrar.err ;; 4) echo 需要密码$pkg /var/log/unrar.err ;; *) echo 其他错误($rc)$pkg /var/log/unrar.err ;; esac把 CRC 错误和需要密码单独记下来很有用。前者说明源文件要重新拉后者说明这批包有统一的密码需要配置两者的处理动作完全不同混在一起记录等于给自己找麻烦。6.3 放进定时任务要注意什么定时批处理最容易出问题的是环境差异手动跑没问题放进定时任务就失败。常见原因是PATH不一样脚本里用了unrar但定时任务的PATH里没有它。解决办法是脚本里用绝对路径或者在开头显式设置PATH。第二是并发。如果上一轮还没跑完下一轮就起来了同一个包可能被解压两遍甚至互相覆盖。加一个锁最省事exec 9/var/lock/unrar-batch.lock flock -n 9 || { echo 上一轮还在跑; exit 0; }flock -n是非阻塞模式拿不到锁就直接退出不会堆积进程。第三是清理。解压出来的临时目录、失败留下的半截文件如果没人管几个月后磁盘就满了。我的做法是在脚本末尾按时间清一遍只保留最近若干天的产物规则写死在脚本里不靠人记得。7. 常见问题速查与排查思路把高频问题集中成一张表遇到时对着查现象大概率原因排查动作提示不认识该格式装的是 free 版不支持新格式unrar看版本号换官方版解压后文件数比预期少用了e导致重名覆盖改用x明确覆盖策略文件名全是乱码打包端编码与本地不一致用-sc指定或convmv事后转找不到下一卷分卷命名不连续ls -1 *.part*.rar排序核对编号报没有权限目标目录属主不对用sudo -u指定解压用户解压到一半停下不动撞上交互式提问加-o或-y脚本里务必关掉询问磁盘莫名被占满解压炸弹或海量小文件lt看总大小l数行数对比df提示 CRC 错误包在传输中损坏重新获取源文件先t再解目录里凭空多出奇怪文件包内混了系统生成的元数据-x排除掉再补三条不成表但很实用的经验。第一条先小范围试。面对一个来源不明的包别直接往重要目录里解。找个临时目录解开看一眼结构确认没问题再搬到正式位置。这个习惯帮我挡过几次包里的目录名和现有目录重名的事故。第二条日志里记版本号。批量任务的日志开头打一行unrar版本出问题时能立刻排除是不是版本差异这个方向。这个细节看起来多余但在跨机器排查时价值很高。第三条别在管道里直接处理解压出来的文件。有人喜欢unrar p archive.rar file | 后续处理p命令确实能把文件内容打到标准输出适合小文件。但一旦文件大、或者处理链路里有任何环节回溯读取就会出问题。大文件老老实实解到磁盘再处理省心得多。我在实际使用中的体会是unrar 这类工具本身没什么复杂度出问题基本都在边界条件上文件名带空格、包有密码、分卷缺一卷、目标目录属主不对、包里混着垃圾文件。把这些边界提前在脚本里处理掉剩下的就是一条稳定的流水线。我现在接手新环境的第一件事就是把上面那套自检加批量脚本落地成模板后面所有压缩包相关的需求都往里套几乎不用再单独想一遍。
阅读完成 · 觉得有帮助?
咨询建站