使用gzip解压后文件大小不符合预期,如何排查及实现错误处理
日志检索方法
Ubuntu默认不会为普通用户执行的gzip命令生成独立系统日志,你可以按照以下优先级排查问题:
- 如果是手动执行脚本,复现问题时给gzip加
-v参数执行gzip -dv $filePath,会直接打印解压过程和实时错误信息 - 如果是cron定时任务执行脚本,执行
grep CRON /var/log/syslog检索cron运行日志,查看任务执行时是否有权限不足、进程被kill、磁盘空间不足相关报错 - 如果是systemd服务托管的脚本,执行
journalctl -u 你的服务名称.service查看服务运行时的完整输出 - 执行
dmesg | grep -i 'io error\|out of memory\|out of space'检索内核日志,排查是否出现磁盘IO故障、系统OOM杀死进程、磁盘空间耗尽导致解压中断的情况 - 执行
gzip -t $filePath校验原压缩包完整性,如果压缩包本身损坏,也会导致解压提前终止,该命令会直接返回校验是否通过的结果。
错误处理逻辑实现
你现有脚本没有任何错误校验逻辑,非常容易出现静默失败的问题,优化后的脚本参考如下:
#!/bin/bash # 开启严格错误模式:遇到命令执行失败、未定义变量、管道错误时直接终止执行 set -euo pipefail filePath="/home/user/theFile" logPath="/var/log/gzip_decompress.log" # 1. 校验压缩包完整性 if ! gzip -t "$filePath"; then echo "$(date '+%Y-%m-%d %H:%M:%S') 错误:压缩包$filePath校验失败,文件已损坏" >> "$logPath" exit 1 fi # 2. 校验磁盘剩余空间,预留32G空间避免解压到一半空间不足 requiredSizeKB=$((32 * 1024 * 1024)) # 此处/home对应你解压目标文件所在的分区,根据实际情况调整 availableSizeKB=$(df /home | awk 'NR==2{print $4}') if [ "$availableSizeKB" -lt "$requiredSizeKB" ]; then availableSizeGB=$((availableSizeKB / 1024 / 1024)) echo "$(date '+%Y-%m-%d %H:%M:%S') 错误:磁盘剩余空间不足,至少需要32G,当前仅剩余${availableSizeGB}G" >> "$logPath" exit 1 fi # 3. 执行解压,将所有输出和错误写入日志 if gzip -d "$filePath" >> "$logPath" 2>&1; then echo "$(date '+%Y-%m-%d %H:%M:%S') 提示:$filePath解压命令执行完成" >> "$logPath" else echo "$(date '+%Y-%m-%d %H:%M:%S') 错误:解压执行失败,错误码$?" >> "$logPath" exit 1 fi # 4. 校验解压后文件大小是否符合预期 # 注意:如果原压缩包后缀不是.gz,需要自行调整解压后文件路径的拼接逻辑 decompressedPath="${filePath%.gz}" minExpectedSizeByte=$((29 * 1024 * 1024 * 1024)) actualSizeByte=$(stat -c%s "$decompressedPath") if [ "$actualSizeByte" -lt "$minExpectedSizeByte" ]; then actualSizeGB=$((actualSizeByte / 1024 / 1024 / 1024)) echo "$(date '+%Y-%m-%d %H:%M:%S') 错误:解压后文件大小不符合要求,预期至少29G,实际仅${actualSizeGB}G" >> "$logPath" # 可选:自动清理不符合要求的错误文件 rm -f "$decompressedPath" exit 1 fi echo "$(date '+%Y-%m-%d %H:%M:%S') 成功:$filePath解压完成,结果符合预期" >> "$logPath" exit 0
相关说明:
- 所有变量用双引号包裹,避免路径中存在空格等特殊字符时出现执行异常
- 所有操作日志都会写入
/var/log/gzip_decompress.log,后续出现问题直接检索该日志即可 - 新增了完整性、空间、结果大小三道校验逻辑,只要不符合预期就会直接返回非0错误码,不会出现静默失败的情况
内容的提问来源于stack exchange,提问作者Baequiraheal
相关产品推荐
相关产品推荐

