【问题标题】:Bash script while loop breaks after running another script运行另一个脚本后循环中断的 Bash 脚本
【发布时间】:2019-10-19 14:00:09
【问题描述】:

在循环运行但循环中断时在 bash 脚本中运行另一个脚本! 注:我提到的脚本只是循环当前目录中的文件并运行 mpirun。 这是我的 bash 脚本:

#!/bin/bash
np="$1"
bin="$2"
ref="$3"
query="$4"
word_size="$5"

i=1;
input="$query"
while read line; 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
        ^^^^^^^^
        #for filename in *.fasta; do
        #    mpirun -np "${np}" "${bin}" -d "${ref}" -ql "${filename}" -k "${word_size}" -b > log
        #    rm $filename
        #done
    fi
    ((i++))
  fi
done < $input

【问题讨论】:

  • 循环何时中断?这个循环退出的唯一方法是如果没有更多数据可以从$query命名的文件中读取。
  • 事实并非如此。还有很多行要读取,但是在第一次 run.sh 运行后循环中断
  • run.sh 是否从标准输入读取?它从循环中继承其标准输入,因此它会在 read line 有机会再次执行之前消耗其余数据。
  • 不,它没有,run.sh 只是循环当前目录中的文件并运行另一个程序并将每个文件传递给刚刚由 run.sh 调用的程序
  • @chepner 是对的,mpirunconsumes stdin

标签: bash


【解决方案1】:

问题是您的run.sh 脚本没有向mpirun 传递任何参数。该脚本将变量${np} ${bin} ${ref} ${filename} ${word_size} 传递给mpirun,但这些变量是主脚本的本地变量,并且在run.sh 中未定义。您可以在主脚本中导出这些变量,以便它们可用于所有子进程,但更好的解决方案是在run.sh 中使用位置参数:

for filename in *.fasta; do
  mpirun -np "${1}" "${2}" -d "${3}" -ql "${4}" -k "${5}" -b > log
  rm $filename
done

【讨论】:

  • 这种方式也不起作用,我说忘记run.sh脚本,如果我调用mpirun而不是调用run.sh,mpirun将正常工作一次,并且在运行mpirun后主while循环中断但是,如果我调用 ls 命令而不是 mpirun 或 run.sh,while 循环会起作用,并且 ls 会运行多次。
  • 那么我怀疑您将参数传递给mpirun 的顺序错误。当然,您应该在传递${bin} 参数之前传递命令行选项及其值。当您直接从命令行而不是通过此脚本调用 mpirun 时会发生什么?
  • 我认为在他的脚本中,$filename 是一个内部变量。所以你可能想要mpirun -np "${1}" "${2}" -d "${3}" -ql "${filename}" -k "${4}" -b &gt; log。没有${5}
【解决方案2】:

我不知道mpirun,但如果你的循环中有任何从stdin 读取的内容,循环就会中断。

【讨论】:

    猜你喜欢
    • 2023-01-13
    • 2023-04-09
    • 2018-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-22
    • 1970-01-01
    相关资源
    最近更新 更多