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 -exec 和 xargs 方式会继续处理后面的文件,只有 && 串联的方式会在出错时中断。想要批量解压后统计失败数量,可以在 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,转载)