Bash脚本while循环调用外部脚本后循环中断问题求助
解决Bash While循环调用脚本后中断的问题
这个坑我踩过好多次!你的问题核心原因很明确:被调用的run.sh会默认读取标准输入,而主脚本里的while read line循环是把$input文件重定向到标准输入来读取的。当run.sh执行时,它会把$input里剩下的内容全部“抢”走,导致主脚本的read命令再也拿不到新的行,循环自然就中断了。
下面给你几个靠谱的解决办法,按优先级排序:
1. 给run.sh调用加上标准输入重定向
最简单的办法就是让run.sh的标准输入来自空设备,这样它就不会碰主脚本的输入流了。修改主脚本里的调用行:
./run.sh "$np" "$bin" "$ref" "$word_size" < /dev/null
顺便提一句,这里给变量加上双引号是好习惯,避免变量里有空格或者特殊字符时出问题。
2. 用独立文件描述符读取输入
如果不想修改run.sh的调用方式,也可以让主脚本的while循环用单独的文件描述符来读取$input,彻底和标准输入划清界限:
# 用文件描述符3来读取input文件 while read line <&3; do echo "$line" if [[ "${line:0:1}" == ">" ]] ; then header="$line" echo "$header" >> seq_"${i}".fasta else seq="$line" echo "$seq" >> seq_"${i}".fasta if ! (( i % 5)) ; then ./run.sh "$np" "$bin" "$ref" "$word_size" fi ((i++)) fi done 3< "$input"
这样不管run.sh怎么用标准输入,都不会影响循环读取$input的内容。
3. 修改run.sh本身(如果有权限的话)
看你注释里的run.sh内容,里面的mpirun命令可能会默认读取标准输入,这也是导致问题的根源之一。可以直接给mpirun加上< /dev/null,让它不读取stdin:
for filename in *.fasta; do mpirun -np "${np}" "${bin}" -d "${ref}" -ql "${filename}" -k "${word_size}" -b > log < /dev/null rm "$filename" done
这样run.sh本身就不会消耗标准输入了,主脚本的循环自然就能正常跑完。
最后再补个小建议:主脚本里的变量引用尽量都加上双引号,比如"$input"、"$line",避免遇到含空格的文件名或内容时出现意外错误。
内容的提问来源于stack exchange,提问作者Amin Rezaei
相关产品推荐
相关产品推荐

