两者完成后如何运行并行进程并合并输出


17

我有一个bash shell脚本,其中通过大约5或6个不同的程序将一些数据通过管道传输,然后将最终结果传输到制表符分隔的文件中。

然后,我对一个单独的相似数据集再次执行相同操作,然后输出到第二个文件。

然后将两个文件输入另一个程序进行比较分析。例如简化

Data1 | this | that |theother | grep |sed | awk |whatever > Data1Res.csv
Data2 | this | that |theother | grep |sed | awk |whatever > Data2Res.csv
AnalysisProg -i Data1res.csv Data2res.csv

我的问题是:如何使step1和step2同时运行(例如,使用&),但在两者均完成时仅启动step3(AnalysisProg)?

谢谢

ps AnalysisProg在流或FIFO上不起作用。



顺便说一句,您可以使用Perl脚本吗?这可以为您简化很多事情,并且您可以非常高效地实施此后处理,并使它毫不费力地并行运行。
Bichoy 2014年

Perl ..不是那么多,不是:(
Stephen Henderson

1
在这里,我演示如何在管道与拆分输入tee和两个并行处理它grep的过程:unix.stackexchange.com/questions/120333/...
mikeserv

在这里我演示了如何使用简单的外壳结构,充分后台进程的方式nohup威力,但仍保持与进程通信的一种手段:unix.stackexchange.com/questions/121253/...
mikeserv

Answers:


27

使用wait。例如:

Data1 ... > Data1Res.csv &
Data2 ... > Data2Res.csv &
wait
AnalysisProg

将:

  • 将Data1和Data2管道作为后台作业运行
  • 等他们俩完成
  • 运行AnalysisProg。

参见例如这个问题


Thx,看起来不错。如果以上方法无效,我将尝试使用此方法。
斯蒂芬·亨德森

THX再次,我是那种知道等待的不过话说一派有点糊涂了它是如何与不同的PID等。我觉得愚蠢的工作,现在我看到它是“等待”
斯蒂芬·亨德森

12

如果您只有2个文件,那么cxw的答案无疑是更好的解决方案。如果这两个文件仅是示例,而实际上您有10000个文件,则'&'解决方案将不起作用,因为这会使服务器超载。为此,您需要一个类似GNU Parallel的工具:

ls Data* | parallel 'cat {} | this | that |theother | grep |sed | awk |whatever > {}res.csv
AnalysisProg -i *res.csv

要了解有关GNU Parallel的更多信息:


嗨,谢谢。目前,我确实有两个文件,但是我有24个处理器,所以我很想一次尝试运行多个对-尽管不是计算机科学领域的人,我不清楚磁盘读取瓶颈是否值得。也许我会吮吸看看;)
Stephen Henderson

@StephenHenderson取决于文件的大小,仍然可以将其保留在缓存中。如果速度至关重要,则可以使用tmpfs(文件是<<<然后是RAM)。
Maciej Piechotka 2014年

1
@StephenHenderson可以使用-j调整并行作业的数量,因此请尝试-j4,如果服务器没有过载,请尝试-j6等。但是请随时按CTRL-C:GNU Parallel是快速重载服务器的出色工具。 。也看看--load。
Ole Tange 2014年

1

一种执行此方法的方法可能类似于:

AnalysisProg <<PREPROCESS /dev/stdin
$( 
{   process1=$( pipe | line | 1 >&2 & echo $! )
    process2=$( pipe | line | 2 >&2 & echo $! )
    while ps -p $process1 $process2 >/dev/null; do
        sleep 1
    done
} 2>&1
)
#END
PREPROCESS

这样,您可以为两个管道提供背景,但仍要等待它们完成执行,然后再将它们的输出合并到stdin中,该stdin在here文档中进行评估并移交给AnalysisProg。如果可以使用wait它,则它甚至比while ps循环更好,但是,取决于外壳程序,wait如果您指示它等待不是当前外壳程序子进程的进程,可以反对

另请注意,上述方法将整理输出-因此两个进程都将被立即写出。如果您希望将它们分开,或将它们附加到另一个,则可以执行以下操作:

AnalysisProg 3<<PREPROCESS /dev/fd/3 /dev/stderr
$(
process1=$(... >&2 ...) 2>/dev/fd/3
...
} 3>/dev/fd/3 2>/dev/stderr
)

我之前已经演示过这些概念。最好的演示可能在这里这里


0

试试这个。

rm -f Data1Res.csv
rm -f Data2Res.csv
Data1 | this | that |theother | grep |sed | awk |whatever > Data1Res.csv &
Data2 | this | that |theother | grep |sed | awk |whatever > Data2Res.csv &
while true
do
  ps aux | grep -v grep | grep -i -E 'Data1Res.csv|Data2Res.csv' &> /dev/null
  if [ $? -ne 0 ]
  then
    AnalysisProg -i Data1res.csv Data2res.csv
    exit 0
  fi
done

好吧,那是沉重的。难道不像重新发明wait轮子吗?
约翰·史密斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.