请求优化并行编译目录层级文件的Shell脚本
优化并行编译脚本,确保清理操作在编译完成后执行
需求说明
需编译src目录下所有.lang文件,保持原目录结构输出到同级build目录:
- 编译成功生成
.lang.out文件 - 编译失败生成
.lang.log文件 - 最后自动清理空的失败日志文件
原脚本通过后台进程实现并行编译,但清理命令会在编译进程未全部完成时提前执行,导致无法正确清理日志。
原脚本存在的问题
- 未等待所有后台编译进程结束就执行清理操作
CURRENTDIR变量存在语法错误(误用${O},应为${0})- 使用
sed做路径替换,效率低于原生Shell变量操作
优化后的脚本
#!/usr/bin/env sh # 修复脚本目录获取逻辑 CURRENTDIR="$(dirname -- "$(readlink -f "$0")")" SRCDIR="${1:-$CURRENTDIR}" BUILDDIR="$(dirname "$SRCDIR")/build" # 编译参数配置 COMPILER="cat" OPTION="" INPUTEXT=".lang" OUTPUTSUCCESSEXT=".out" OUTPUTFAILUREEXT=".log" compile () { local f="$1" # 用Shell原生替换生成输出目录 local dir="${f/$SRCDIR/$BUILDDIR}" dir="${dir%/*}" mkdir -p "$dir" # 生成成功输出文件路径 local success="${f/$SRCDIR/$BUILDDIR}" success="${success/%$INPUTEXT/$INPUTEXT$OUTPUTSUCCESSEXT}" # 生成失败日志文件路径 local failure="${f/$SRCDIR/$BUILDDIR}" failure="${failure/%$INPUTEXT/$INPUTEXT$OUTPUTFAILUREEXT}" # 执行编译命令 "$COMPILER" "$OPTION" "$f" >"$success" 2>"$failure" } # 存储所有编译进程的PID pids=() # 遍历所有待编译文件,后台执行编译 find "$SRCDIR" -type f -iname "*$INPUTEXT" | while IFS= read -r f do compile "$f" & pids+=($!) done # 等待所有编译进程完成 for pid in "${pids[@]}"; do wait "$pid" done # 清理空的失败日志 find "$BUILDDIR" -type f -iname "*$OUTPUTFAILUREEXT" -empty -exec rm {} \; exit 0
核心优化点
- 等待后台进程:通过数组记录每个编译进程的PID,遍历执行
wait命令,确保所有编译完成后再执行清理 - 修复路径变量:修正
CURRENTDIR的语法错误,正确获取脚本所在目录 - 高效路径替换:改用Shell原生变量替换语法替代
sed,减少外部命令调用,提升脚本执行效率 - 局部变量隔离:在
compile函数中用local声明变量,避免全局变量污染
内容的提问来源于stack exchange,提问作者uNouss
相关产品推荐
相关产品推荐

