最直接方案是unzip -O GBK解压:Windows ZIP默认用GBK/GB18030编码存文件名,Linux unzip默认UTF-8解析,不指定即乱码;新版unzip 6.0+支持该参数,需注意-O在包名前、-d在包名后,顺序错误会报错。

unzip -O GBK 是最直接的解压中文名方案
Windows 打包的 .zip 文件默认用 GBK(或 GB18030)编码写入文件名,而 Linux 的 unzip 默认按 UTF-8 解析,不指定就必然乱码。新版 unzip(6.0+)支持 -O 参数强制指定原始编码:
-
unzip -O GBK archive.zip -d ./output/—— 最常用组合,指定编码 + 指定目录 -
unzip -O GB18030 archive.zip -d ./output/—— 对某些 Win11/新 Office 打包更稳妥 -
unzip -O CP936 archive.zip -d ./output/——CP936是GBK的 Windows 代码页别名,效果等价
注意:-O 必须放在压缩包路径之前,否则会被忽略;-d 必须放在压缩包路径之后,顺序错就报错。
你的 unzip 不支持 -O?先确认版本再升级或换工具
运行 unzip -v 查看版本。低于 6.0 的旧版(如 Debian 11 自带的 6.0 之前版本、CentOS 7 默认的 6.0 以下)确实不带 -O。这时不要硬套命令:
- Ubuntu/Debian:运行
sudo apt update && sudo apt install unzip升级到最新版 - CentOS/RHEL 7:需手动编译或启用 EPEL 后安装较新源,
yum install epel-release && yum install unzip - 实在无法升级:改用
unar(来自atool包),它原生支持编码参数:unar -e GBK archive.zip - 或者用
7z:装好p7zip-full后执行LANG=C 7z x archive.zip -o./output/,它对中文名兼容性更好
批量解压时别用 unzip *.zip,会静默出错
这是运维现场最高频的误操作:unzip *.zip 看似省事,实际 shell 展开后变成 unzip a.zip b.zip c.zip,unzip 只把第一个当包,其余全当“包内文件名”去搜——根本不存在,于是报一堆 caution: filename not matched,但解压动作却只发生在第一个包上,其余全被跳过。
真正安全的批量解压写法是:
- 逐个处理:
for z in *.zip; do unzip -O GBK "$z" -d "./extracted/${z%.zip}"; done - 加错误检查:
for z in *.zip; do unzip -O GBK -t "$z" >/dev/null && unzip -O GBK "$z" -d "./out/"; done(先校验再解) - 避免覆盖风险:加
-n(已存在则跳过)或-o(强制覆盖),根据场景选
解压后文件权限和归属不是 zip 的责任
zip 格式本身不存储 Unix 权限位和用户组信息,所以无论你怎么指定编码,解压出来的文件默认属主是你当前用户,权限是 644(普通文件)或 755(可执行文件),不会还原原始的 750、600 或 root:www-data 这类设置。
如果业务依赖特定权限或属主(比如部署脚本、Web 静态资源),解压后必须手动补:
- 批量加执行权:
find ./output -name "*.sh" -exec chmod +x {} \; - 统一改属主:
chown -R www-data:www-data ./output/ - 注意:这些操作不能靠
unzip参数完成,得额外加步骤
真正容易被忽略的是:乱码只是表象,背后是编码、工具链、权限三层脱节。你得先确认 unzip -v 版本,再决定用 -O 还是换 unar 或 7z,最后还得补权限——少一步,上线就可能失败。











