You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何unzip -tqq未返回错误码1且仍输出信息?脚本如何检测zip损坏?

如何正确检测最新ZIP文件是否损坏并抑制错误输出

尝试在bash脚本中用if-else检测文件夹中最新创建的ZIP归档文件:文件正常执行if分支,损坏则执行else分支。但使用unzip -tqq检测损坏的ZIP时,不仅脚本逻辑未按预期工作,还会输出类似file #1: bad zipfile offset (local header sig): 0的信息。测试脚本如下:

if $(ls -Art ~/*.zip | tail -n 1 | xargs unzip -tqq);then
    echo 'file is ok'
else 
    echo 'file is corrupt'
fi

尝试过zip -T、unzip -tq等方式,错误信息依然会输出。可通过dd if=/dev/zero of=<filename>.zip bs=1 count=1 seek=1 conv=notrunc命令损坏ZIP文件来复现问题。疑问:为什么-qq选项无法抑制所有可读信息?如何实现预期的检测逻辑?

正确实现方案

1. 修正if语句逻辑,直接判断命令退出码

if后无需使用$(...),直接执行检测命令即可,if会根据命令的退出码(0为成功,非0为失败)判断分支,同时将错误输出重定向到/dev/null:

latest_zip=$(ls -Art ~/*.zip | tail -n 1)
if unzip -tqq "$latest_zip" 2>/dev/null; then
    echo 'file is ok'
else
    echo 'file is corrupt'
fi

2. 更安全的获取最新ZIP文件的方式

ls输出在文件名包含空格、特殊字符时会出错,推荐用find结合stat来精准获取最新文件:

latest_zip=$(find ~ -maxdepth 1 -type f -name "*.zip" -printf "%T@ %p\n" | sort -n | tail -1 | cut -d' ' -f2-)
if unzip -tqq "$latest_zip" 2>/dev/null; then
    echo 'file is ok'
else
    echo 'file is corrupt'
fi

问题原因解析

  1. if语句写法错误:
    使用if $(...)会把unzip的输出当作要执行的shell命令,而非判断unzip的退出码。比如unzip无输出时,相当于执行if true(空命令退出码为0),完全偏离了检测文件是否损坏的逻辑。正确写法是直接将检测命令放在if后,由if自动判断其退出码。

  2. -qq选项仅抑制标准输出:
    unzip的-q/-qq选项仅屏蔽标准输出(stdout)的正常提示信息,而错误信息会输出到标准错误(stderr),因此需要用2>/dev/null将stderr重定向到/dev/null,才能彻底屏蔽错误内容。

内容的提问来源于stack exchange,提问作者xdobx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 17:42:45