MacOS+Homebrew下带进度条的tar+ZSTD --ultra 22压缩问题
解决tar+zstd无中间文件压缩并显示正确进度的问题
问题说明
需要在终端中压缩文件或文件夹并查看实时压缩进度,但现有脚本存在两个问题:
- 必须生成中间tar文件才能完成压缩,效率低且占用额外磁盘空间
- 进度条会直接跳到100%并停滞,直到压缩完全结束,无法显示真实进度
现有脚本:
#!/bin/bash # Exit script if any command fails set -e # Check that two arguments are passed if [ $# -ne 2 ]; then echo "Usage: $0 <directory_to_compress> <output_file>" exit 1 fi # Check if required commands are available for cmd in du tar zstd pv; do if ! command -v $cmd &> /dev/null; then echo "Error: $cmd could not be found. Please install it." exit 1 fi done DIRECTORY_TO_COMPRESS="$1" OUTPUT_FILE="$2" # Create the tar file tar -cvf "$OUTPUT_FILE.tar" "$DIRECTORY_TO_COMPRESS" # Compute the size of the tar file in bytes SIZE=$(du -sh "$OUTPUT_FILE.tar" | cut -f 1) SIZE_BYTES=$(echo $SIZE | awk '/^.*[0-9\.]+[Kk]?$/{printf "%.0f", $1*1024}; /^.*[0-9\.]+[Mm]?$/{printf "%.0f", $1*1024*1024}; /^.*[0-9\.]+[Gg]?$/{printf "%.0f", $1*1024*1024*1024};') # Compress the tar file with zstd using pv for progress pv -p -s ${SIZE_BYTES} "$OUTPUT_FILE.tar" | zstd -T0 --ultra -22 > "$OUTPUT_FILE.tar.zst" # Remove the intermediate tar file rm "$OUTPUT_FILE.tar" echo "Compression completed successfully. Output file is $OUTPUT_FILE.tar.zst"
修复后的脚本
#!/bin/bash set -e # 参数检查 if [ $# -ne 2 ]; then echo "Usage: $0 <directory_to_compress> <output_file>" exit 1 fi # 依赖检查 for cmd in du tar zstd pv; do if ! command -v "$cmd" &> /dev/null; then echo "Error: $cmd 未找到,请先安装。" exit 1 fi done SOURCE="$1" OUTPUT="$2.tar.zst" # 获取源目录/文件的准确字节大小 TOTAL_SIZE=$(du -sb "$SOURCE" | cut -f1) # 流式压缩:tar打包 -> pv显示进度 -> zstd压缩 tar -cf - "$SOURCE" | pv -p -s "$TOTAL_SIZE" | zstd -T0 --ultra -22 > "$OUTPUT" echo "压缩完成,输出文件:$OUTPUT"
关键改动说明
- 移除中间tar文件:使用
tar -cf -将打包内容输出到标准输出,直接通过管道传递给zstd,全程无磁盘写入中间文件 - 修复进度条问题:用
du -sb直接获取源文件/目录的原始字节数,作为pv的-s参数,确保进度条能准确反映已处理的数据量 - 保留zstd高级参数:管道方式完全支持
--ultra和-T0(自动使用所有CPU核心)参数,不影响压缩效率和级别 - 简化流程:去掉了中间文件的创建、大小计算、删除等冗余步骤,脚本更简洁高效
内容的提问来源于stack exchange,提问作者OpenGears
相关产品推荐
相关产品推荐

