병렬 프로세스를 실행하고 두 프로세스가 완료된 후 출력을 병합하는 방법

병렬 프로세스를 실행하고 두 프로세스가 완료된 후 출력을 병합하는 방법

나는 약 5~6개의 다른 프로그램을 통해 일부 데이터를 파이프한 다음 최종 결과를 탭으로 구분된 파일에 저장하는 bash 쉘 스크립트를 가지고 있습니다.

그런 다음 별도의 유사한 데이터세트로 동일한 작업을 다시 수행하고 이를 두 번째 파일로 출력합니다.

두 파일은 비교 분석을 위해 다른 프로그램에 입력됩니다. 예를 들어 단순화

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

제 질문은: 1단계와 2단계를 동시에 실행하도록 하려면(예: & 사용), 두 단계가 모두 완료된 경우에만 3단계(AnalyticProg)를 시작하려면 어떻게 해야 합니까?

감사해요

ps AnalysisProg는 스트림 또는 fifo에서 작동하지 않습니다.

답변1

사용 wait. 예를 들어:

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

할 것이다:

  • Data1 및 Data2 파이프라인을 백그라운드 작업으로 실행
  • 둘 다 끝날 때까지 기다리세요
  • AnalysisProg를 실행합니다.

예를 들어 다음을 참조하세요.이 문제.

답변2

파일이 2개만 있는 경우 cxw의 답변이 확실히 더 나은 솔루션입니다. 이 2개 파일은 단지 예일 뿐이고 실제로 10,000개의 파일이 있는 경우 "&" 솔루션은 서버에 과부하를 일으키므로 작동하지 않습니다. 이를 위해서는 GNU Parallel과 같은 도구가 필요합니다.

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

GNU 병렬에 대해 자세히 알아보려면:

답변3

이를 수행하는 한 가지 방법은 다음과 같습니다.

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

이렇게 하면 두 파이프라인을 모두 백그라운드로 설정할 수 있지만 출력을 여기 문서에서 평가되어 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
)

나는 이전에 이러한 개념을 시연한 적이 있습니다. 최고의 데모는 아마도여기그리고여기.

답변4

이것을 사용해보십시오.

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

관련 정보