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


17

약 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 (AnalysisProg) 만 시작할 수 있습니까?

고마워

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


이것을 확인하십시오 : pebblesinthesand.wordpress.com/2008/05/22/…
Bichoy

BTW, Perl 스크립트를 사용해도 되나요? 이를 통해 문제를 크게 단순화 할 수 있으며이 사후 처리를 매우 효율적으로 구현하고 손쉽게 병렬로 실행할 수 있습니다.
Bichoy

Perl ..별로, 아니 :(
Stephen Henderson

1
여기에서는 tee두 개의 동시 grep프로세스로 파이프를 통해 입력을 분할 하고 처리 하는 방법을 보여줍니다 . unix.stackexchange.com/questions/120333/…
mikeserv

그리고 여기에서는 간단한 쉘 구조를 사용하여 프로세스를 완전히 백그라운드로 처리 nohup하지만 프로세스와의 통신 수단을 유지하는 방법을 보여줍니다. unix.stackexchange.com/questions/121253/…
mikeserv

답변:


27

사용하십시오 wait. 예를 들면 다음과 같습니다.

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

의지:

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

예를 들어이 질문을 참조하십시오 .


Thx, 좋아 보인다. 위의 방법으로 문제가 해결되지 않으면 시도해 보겠습니다.
Stephen Henderson

들으 다시, 나는 일종의 대기의 인식의했지만 조금 지금은 그냥 "대기"입니다 참조는 다른 PID 등 I 느낌 바보와 협력하는 방법에 혼란스러워했다 봤 한
스티븐 헨더슨

12

cxw의 대답은 의심 할 여지없이 2 개의 파일 만 있으면 선호되는 솔루션입니다. 2 개의 파일이 단지 예이고 실제로 10000 개의 파일이있는 경우 '&'솔루션이 작동하지 않아 서버에 과부하가 발생합니다. 이를 위해서는 GNU Parallel과 같은 도구가 필요합니다.

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

GNU Parallel에 대해 더 배우려면 :


안녕하세요 thx. 현재 두 개의 파일이 있지만 24 개의 프로세서가 있으므로 한 번에 여러 쌍을 시도해보고 싶은 유혹을 느꼈습니다.하지만 컴퓨팅 과학 전문가는 아니지만 디스크 읽기 병목 현상이 가치가 있는지는 확실하지 않습니다. 어쩌면 내가 그것을 빨아보고;)
Stephen Henderson

@StephenHenderson은 크기에 따라 파일이 여전히 캐시에있을 수 있습니다. 속도가 중요한 경우 tmpfs를 사용할 수 있습니다 (파일은 <<<이고 RAM입니다).
Maciej Piechotka

1
@StephenHenderson 병렬 작업의 수는 -j를 사용하여 조정할 수 있으므로 -j4를 시도하고 서버에 과부하가 걸리지 않으면 -j6 등을 시도하십시오. 그러나 CTRL-C를 누를 준비가되었습니다. GNU Parallel은 서버를 빠르게 과부하시키는 훌륭한 도구입니다. . --load도 살펴보십시오.
Ole Tange

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

이런 식으로 두 파이프 라인을 모두 배경으로하지만 출력을 여기 문서에서 평가하여 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
)

이전에 이러한 개념을 시연했습니다. 아마도 최고의 데모가 여기있습니다 .


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의 바퀴를 재발 명하는 것과 같지 않습니까?
John WH Smith
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.