이것은 내 스크립트입니다.
#! /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
완료되자마자 실행해야 하고, 완료되자마자 실행해야 한다는 뜻입니다.P1
cat $file_out2
P2
또한 P1이 성공적으로 종료되고 P2도 성공적으로 종료되는지 확인하고 싶습니다. 마지막으로, 둘 P1
중 하나에 오류가 있는지 어떻게 알 수 있습니까 P2
?
이 스크립트에서는 $ret
작동하지 않습니다(항상 exit 0
). 실행한 후에는 $ret
에서 왔는지 P1
여부를 아는 것이 좋을 것입니다 P2
. 예를 들어, 반환 코드 x1 과 반환 코드 x2 P1
가 있습니다 . P2
0이 아닌 종료 코드가 있으면 프로그램은 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
당신은 얻을 것이다. 예측할 수 없습니다.127
0
여러분의 바람은 순차적으로 실행하는 것과 동일한 피드백을 얻으면서 병렬성과 소스 최소화의 지속 시간 이점을 얻는 것입니다.
자체 상자에서 실행하고, 출력 경합을 관리하고( 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