使bash停止移动到脚本中的下一行,直到共享进程结束

时间:2014-09-03 00:06:24

标签: bash

我正在执行一个命令a,它将脚本input.sh作为输入并运行二进制program,它生成一些输出文件outputinput.sh有一行NUMPROCS={some number},用于指定处理器program使用的数量。 aprogram运行时立即给予我控制权。输出文件末尾有一行告诉我program花了多长时间。

我想在一个循环中运行它,以查看时间program作为处理器数量的函数。如何让控件等到output在每个循环中生成(因此grep得到正确的值),然后再转到第4行?

到目前为止我的脚本如下。第3行是NUMPROCS具有固定值时的运行方式。

一些问题:其他用户也运行program,因此我无法直接使用pidof programwait

1 #! /bin/bash
2 for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16; do
3     a input.sh
4     E=`grep "Elapsed Time" output`
5     sed -i "/NUMPROCS/c\NUMPROCS=${i}" input.sh 
6     echo $i $E >> result.dat
7 done
8 cat result.dat

1 个答案:

答案 0 :(得分:0)

这听起来像是你的input.sh脚本(旁注,如果这是一个命令行命令,它最后不应该有.sh),另一方面,如果它被读入“a”程序shell包含“。”或“source”,.sh很好)将其作业内部并立即退出,使所有子工作都运行。理想情况下,您需要编辑input.sh,以在生成作业后使用“wait”命令(可能是命令行选项可触发的行为)。当然,如果你可以编辑它,你显然想要在命令行上添加等待来指定作业计数,然后突然间一切都会非常简单。

另一方面,使用sed编辑脚本实际上只有在确实是shell脚本导入时才有意义,这种方法很难传递命令行参数(将它们传递给“a”是容易,但对于input.sh,它需要从“a”的内部变量中取出它们,这是非常不正常的)。显然,做任何整洁的事情都是一个困难的模式。在这种情况下,您可以选择解析输出以查找指示多个执行完成的行,或者使用“ps”和“grep”来计算运行的数量并继续下一个完成后循环迭代(还有一个非常恶心的方法,你循环直到系统负载再次达到最低点,但肯定没人会这样做。)

每次编辑input.sh脚本都不是很好,因为这意味着如果你一起运行多个测试,它们可能会相互干扰 - 在极少数情况下,显着。

所以,虽然这比修复input.sh或“a”本身要难得多,但你可以在“a input.sh”后添加这样的循环

while true ; do
    if [ $i -eq `grep -c 'Elapsed Time' output | wc -l` ] ; then
        break
    fi
    sleep 10  # avoid zillions of greps in a given time interval.
done

如果没有关于input.sh的更多信息,很难提供更好的建议。修复input.sh本身或“a”程序,以便有一个等待子工作完成的选项,通常是首选的方法。

其他说明:

  • “#!/ bin / bash”通常不应该在幻数之后有空格。
  • 使用“for i in {1..16}; do”代替 - 更容易改变(假设中途现代bash)
  • E = grep "Elapsed Time" output嵌套命令输出捕获,这意味着它将尝试执行grep的行输出。这可能不是你想要的。
  • 您可以删除“>> result.dat”和cat,而是将“done”更改为“done | tee result.dat”以获得相同的效果。