프로세스가 완료될 때만 전체 출력 표시

프로세스가 완료될 때만 전체 출력 표시

이것은 내 스크립트입니다.

#! /bin/bash

ret=0
file_out1=$(mktemp)
file_out2=$(mktemp)

(echo first start; sleep 2s; echo first finish;) &> $file_out1 &
ret=$?
P1=$!
(echo second start; sleep 1s; echo second finish;) &> $file_out2 &
ret=$?
P2=$!

wait $P1 $P2 || ret=$?

cat $file_out1
cat $file_out2

exit $ret

여기서 출력은 다음과 같습니다.

first start
first finish
second start
second finish

하지만 출력은 다음과 같아야 합니다.

second start
second finish
first start
first finish

내 말은, cat $file_out1완료되자마자 실행해야 하고, 완료되자마자 실행해야 한다는 뜻입니다.P1cat $file_out2P2

또한 P1이 성공적으로 종료되고 P2도 성공적으로 종료되는지 확인하고 싶습니다. 마지막으로, 둘 P1중 하나에 오류가 있는지 어떻게 알 수 있습니까 P2?

이 스크립트에서는 $ret작동하지 않습니다(항상 exit 0). 실행한 후에는 $ret에서 왔는지 P1여부를 아는 것이 좋을 것입니다 P2. 예를 들어, 반환 코드 x1 과 반환 코드 x2 P1가 있습니다 . P20이 아닌 종료 코드가 있으면 프로그램은 0이 아닌 반환 코드로 종료됩니다.

업데이트 1:

하나askubuntu로 답변됨--group, 각 명령의 출력이 명령이 완료될 때까지 기다리도록(혼합 출력 방지) 병렬 명령의 매개변수를 사용할 수 있는 것이 좋습니다 .

표시되는 명령은 입니다 parallel --group 'echo -n {};sleep {};echo {}' ::: 1 3 2 4.

이 명령은 내 컴퓨터에서 작동합니다. 그러나 내 상황에서 이 명령을 사용하는 방법을 이해할 수 없습니다.

내 말은, 내가 어떻게 얻을 수 있단 말인가?

second start
second finish
first start
first finish

echo first start; sleep 2s; echo first finish;gnu를 사용 하면서 동시에 명령을 입력하는 경우 echo second start; sleep 1s; echo second finish;.

업데이트 2:

현재 내가 사용하는 코드는 다음과 같습니다.

#! /bin/bash

function first {
    echo first start
    sleep 2s
    echo first finish
}
function second {
    echo second start
    sleep 1s
    echo second finish
}

export -f first && export -f second

parallel -j2 ::: first second

이것은 실제로 내 문제를 해결했습니다.

답변1

각 작업이 종료되자마자 출력을 표시하기를 원할 것 같지만 출력을 축소하지 않도록 하세요. 그래서 파일에 버퍼링하는 것입니다. 괜찮습니다. 출력 앞에 sed를 붙여서 나타날 때 표시되도록 할 수도 있습니다. 그런 다음 필요에 따라 다시 정렬합니다. 이는 예측할 수 없는 데이터 볼륨과 스토리지 오버플로 위험을 방지하기 위한 것입니다.

귀하의 오류:

  • 백그라운드 프로세스를 분기하면 &최종 상태에 액세스할 수 없습니다(예상하는 것과는 ret=$?다릅니다).
  • 완료될 때까지 기다리면 어느 프로세스가 먼저 종료될지, 각 프로세스의 최종 상태를 제 시간에 캡처할지 여부를 예측할 수 없습니다 wait. 프로세스가 종료된 후에는 프로세스의 최종 상태가 다음과 같더라도 너무 늦습니다. , wait당신은 얻을 것이다. 예측할 수 없습니다.1270

여러분의 바람은 순차적으로 실행하는 것과 동일한 피드백을 얻으면서 병렬성과 소스 최소화의 지속 시간 이점을 얻는 것입니다.

자체 상자에서 실행하고, 출력 경합을 관리하고( flock파일 설명자가 깨끗함) 최종 상태를 어딘가에 기록하도록 강제합니다. 다시 말하지만, 파일 설명자는 깨끗합니다.

편집하다@AhmadIsmail 편집자가 말했듯이 GNU Parallel은 올인원 솔루션입니다. 어쨌든, 이대로 놔두세요.

#!/bin/bash
# wrap background
mybackground(){
 tmp=$(mktemp) && trap "rm -f $tmp" RETURN
 exec {safe1}>&1 {safe2}>&2 1>$tmp 2>$tmp # swap descriptors
 (eval $@) # work
 echo $? >&$fdstatus # report status 
 exec >&$safe1 2>&$safe2 # restore descriptors
 flock 1 cat $tmp # report output
}
(
mybackground "echo first start; sleep 2s; echo first finish;exit 2" &
mybackground "echo second start; sleep 1s; echo second finish" &
) {fdstatus}> >(
  while read rc;do ((sum+=rc));done;echo sum=$sum;exit $sum ## collect & sum status
) | cat # wait {fdstatus} termination

관련 정보