Bash脚本持续重复执行run.sh处理首个fastq文件问题排查
问题分析与修复方案
核心问题
脚本每次检测到signal为1时,都会遍历目标目录下的所有.fq.gz文件并调用run.sh处理,但处理完成后没有对已处理文件做任何标记(移走、重命名等),导致下一次循环(当signal再次为1时)会重复处理这些文件。另外,原脚本的文件遍历写法存在匹配范围过宽、特殊字符兼容差的问题。
具体修复步骤
1. 精准遍历目标文件
原脚本中for file in $inputdir"/*"会匹配目录下所有文件,改成只匹配.fq.gz格式的文件,同时兼容文件名含空格的情况:
for file in "$inputdir"/*.fq.gz do # 跳过目录下没有匹配文件的情况 [[ -e "$file" ]] || continue # 后续处理逻辑 done
2. 处理后标记已完成文件
处理完文件后必须将其移走或重命名,避免重复处理。推荐两种方案:
- 方案一:移到专门的已处理目录(需提前创建
processed子目录)
# 只有run.sh执行成功,才移动文件 nohup ./run.sh "$file" > "run-$tgchay" && mv "$file" "$inputdir/processed/" &
- 方案二:给文件添加已处理后缀
nohup ./run.sh "$file" > "run-$tgchay" && mv "$file" "$file.processed" &
3. 优化文件计数逻辑
原代码用ls统计文件数的写法在文件名含特殊字符时会出错,改成更可靠的方式:
# 启用nullglob让无匹配时返回空,避免统计错误 shopt -s nullglob files=("$inputdir"/*.fq.gz) num_count=${#files[@]} shopt -u nullglob
完整修复后的脚本
#!/bin/bash signalfile="signal/signal" loopfile="signal/loop" inputdir="/home/ubuntu/Documents/test/8/raw" # 自动创建已处理目录(不存在的话) mkdir -p "$inputdir/processed" checkloop(){ r=$(cat "$loopfile") while [ "$r" == "1" ] do loop=$(cat "$signalfile") if [[ "$loop" == "0" ]] then sleep 10s elif [[ "$loop" == "1" ]] then # 统计目标文件数量 shopt -s nullglob files=("$inputdir"/*.fq.gz) num_count=${#files[@]} shopt -u nullglob if [[ "$num_count" == "0" ]] then sleep 10s else for file in "${files[@]}" do tgchay=$(date +"%d%m%y-%T") echo "Begin processing with $(basename "$file")" # 处理成功后移动文件到已处理目录 nohup ./run.sh "$file" > "run-$tgchay" 2>&1 && mv "$file" "$inputdir/processed/" & done fi fi # 更新循环状态 r=$(cat "$loopfile") done if [ "$r" == "0" ] then echo "Loop terminated by emergency switch!" fi } checkloop
额外提示
- 所有文件路径都用双引号包裹,避免文件名含空格、特殊字符时出错。
- 可以把
nohup的标准错误也重定向到日志文件(2>&1),方便排查问题。 - 确保
run.sh能正确接收并处理传入的文件路径参数。
内容的提问来源于stack exchange,提问作者khanhlpbao
相关产品推荐
相关产品推荐

