CentOS 批量解压多个 zip 文件的几种方法

用 CentOS 做网站部署的都知道,从备份中心或对象存储下载回来的往往是一堆 zip 包:主题包、插件包、日志归档、某个时段的全站备份。一个一个解压不仅慢,还容易漏。本文整理四种批量解压方式,覆盖从几个文件到成百上千个文件的场景。

开始前先用 unzip 确认命令已安装。

一、先安装解压工具

yum install unzip -y

如果还需要解压 rar 文件,可一并安装 unrar:

yum install unrar -y

unzip 本身很小,装上之后不占多少空间,建议作为基础工具常备。

二、进入文件所在目录

cd /path/to/zips

然后根据情况选择下面几种方法之一。

方法一:用分号或 && 隔开(适合数量较少时)

unzip a.zip && unzip b.zip && unzip c.zip

或者:

unzip a.zip; unzip b.zip; unzip c.zip

两者的区别:&& 表示前一个成功才执行下一个,某个包损坏时会中断,方便发现问题;; 则不管成败都会继续。只有三五个文件时,这种方式最直观。

方法二:使用 find 配合 -exec

find . -name '*.zip' -exec unzip {} \;

该命令会递归查找当前目录下所有 .zip 文件并逐个解压,适合文件分散在不同子目录的场景。{} 是 find 的占位符,\; 表示每条结果执行一次。担心文件名带空格的话,可以换成 find . -name '*.zip' -print0 | xargs -0 -n1 unzip -o

方法三:使用 ls 配合 xargs(推荐)

ls *.zip | xargs -n1 unzip -o
  • -n1:每次只向 unzip 传递一个文件名(注意这里是数字 1,不是字母 l);
  • -o:覆盖方式解压,不提示确认。

如果需要解压带密码的 zip 文件,可以加 -P 参数:

ls *.zip | xargs -n1 unzip -o -P 密码

注意:把密码直接写在命令行里会留在 shell 历史记录中,临时用可以,生产环境建议改用交互输入。

方法四:使用 for 循环

for i in *.zip
do
    unzip -o $i
done

for 循环的好处是可以加逻辑:比如解压前先建目录、解压后删除源包、统计失败数量。想更灵活就用它。

批量解压指定前缀的文件

例如要覆盖解压所有 ab 开头的 zip 文件:

ls ab*.zip | xargs -n1 unzip -o

小结

场景 推荐命令
文件数量少 unzip a.zip && unzip b.zip
目录下所有 zip find . -name '*.zip' -exec unzip {} \;
覆盖解压当前目录 zip ls *.zip | xargs -n1 unzip -o
解压带密码的 zip ls *.zip | xargs -n1 unzip -o -P 密码
指定前缀 ls ab*.zip | xargs -n1 unzip -o

实际场景举例

上线新站点时,如果主题和插件都是 zip 归档,常见的做法是:

cd /www/wwwroot/mysite/wp-content/themes
ls *.zip | xargs -n1 unzip -o
chown -R www:www /www/wwwroot

解压完顺便把属主权限修正,避免后续页面提示无法写入。解压日志备份同理,先解压到临时目录、校验无误后再覆盖线上文件,比直接原地解压更安全。

解压到指定目录

默认情况下 unzip 会把文件解压到当前目录,容易和压缩包内部的目录结构混在一起。想统一输出到目标目录,可以用 -d 参数:

mkdir -p /www/wwwroot/uploads
ls *.zip | xargs -n1 unzip -o -d /www/wwwroot/uploads

日志、备份类文件就不会散落在当前目录。批量操作前建议先抽一个包确认内部结构,用 unzip -l 查看:

unzip -l a.zip | head -20

几个常用参数

除了 -o-P,还有两个参数日常很常用:

  • -q:安静模式,解压时不打印每个文件的详细信息,几百个包一起处理时终端不会被刷屏;
  • -n:只解压目标目录中不存在的文件,已存在的直接跳过,适合“补齐缺失文件”而不是整体覆盖。

批量解压时还可以把 find -exec\; 换成 +,让 find 一次性把多个文件名交给同一个 unzip 进程:

find . -name '*.zip' -exec unzip -o {} +

这样减少了进程启动次数,文件数量很多时比逐条执行更快。

解压不受信任文件的注意事项

从网上下载的 zip 包,解压前要留意路径穿越(zip slip)风险:恶意构造的包可能带有 ../ 条目,解压时把文件写到目标目录之外,甚至覆盖系统文件。解压前先执行 unzip -l 检查条目路径,发现包含 .. 的条目就整包丢弃。生产服务器上尤其要养成这个习惯,线上目录被覆盖的代价远比解压慢一点高得多。

常见问题

Q:几百个 zip 一次解压会不会很慢?
A:unzip 是单线程的,文件多时可以用 xargs -P 并行解压提升速度:

ls *.zip | xargs -P4 -n1 unzip -o

-P4 表示同时跑 4 个解压进程,文件多时能明显提速,但要注意磁盘 IO 和内存占用。

Q:解压后想自动删除源包释放空间?
A:确认解压成功后,在 for 循环里加一行 rm -f "$i"。生产环境建议保留源包一段时间,出问题还能重新解压,确认无误后再手动清理。
A:find -execxargs 方式会继续处理后面的文件,只有 && 串联的方式会在出错时中断。想要批量解压后统计失败数量,可以在 for 循环里检查退出码:

for i in *.zip; do
  if unzip -o "$i" > /dev/null 2>&1; then
    echo "OK: $i"
  else
    echo "FAIL: $i"
  fi
done

Q:文件名包含中文或空格怎么办?
A:find -print0 | xargs -0 能稳妥处理带空格的路径;如果文件名是中文且乱码,通常是 zip 的编码问题,可以先用 unzip -O gbk 指定编码再解压。

Q:解压前怎么检查磁盘空间够不够?
A:用 du -ch *.zip | tail -1 看压缩包总大小,再对比 df -h 的剩余空间。压缩比高的日志包解压后体积可能膨胀几倍,别在磁盘快满时盲目批量解压。

其中 xargs 方式在批量解压时最为好用,-n1 是关键参数(数字 1 不是字母 l)。批量压缩文件夹的方法可以参考Linux 中批量压缩文件夹。更多服务器运维内容请查看云服务器分类。

参考:unzip 手册 https://man7.org/linux/man-pages/man1/unzip.1.html,原文链接:https://www.cnblogs.com/cqzhuomi/articles/17284290.html(博客园 CQZHUOMI,转载)