병렬 프로세스를 실행하고 둘 다 완료되면 출력을 결합하는 방법

병렬 프로세스를 실행하고 둘 다 완료되면 출력을 결합하는 방법

나는 약 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

내 질문은: 어떻게 step1과 step2를 동시에 실행하도록 만들 수 있습니까(예: & 사용), 둘 다 완료되었을 때 step3(AnalyticProg)만 실행합니까?

고마워

ps AnalysisProg는 스트림이나 FIFO에서 작동하지 않습니다.

답변1

사용 wait. 예를 들어:

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

할 것이다:

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

예를 들어,이 질문.

답변2

파일이 2개만 있는 경우 cxw의 답변은 의심할 여지 없이 바람직한 솔루션입니다. 2개의 파일은 단지 예일 뿐이고 실제로는 10000개의 파일이 있는 경우 '&' 솔루션은 작동하지 않습니다. 서버에 과부하가 걸리기 때문입니다. 이를 위해서는 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에 전달되는 stdin으로 결합하기 전에 실행이 완료될 때까지 기다립니다. 당신이 사용할 수 있다면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

관련 정보