bash - 디스크에 쓰지 않고도 여러 백그라운드 명령의 출력을 캡처할 수 있습니까?

bash - 디스크에 쓰지 않고도 여러 백그라운드 명령의 출력을 캡처할 수 있습니까?

병렬화하려는 여러 파이프라인이 포함된 스크립트가 있습니다. 현재는 다음과 같습니다.

result1=$(pipeline | number | one)
result2=$(pipeline | number | two)
result3=$(pipeline | number | three)

printf 'Result 1: %s\n' "$result1"
printf 'Result 2: %s\n' "$result2"
printf 'Result 3: %s\n' "$result3"

나는 이것을하고 싶다 :

result1=$(pipeline | number | one) &
result2=$(pipeline | number | two) &
result3=$(pipeline | number | three) &

printf 'Result 1: %s\n' "$result1"
printf 'Result 2: %s\n' "$result2"
printf 'Result 3: %s\n' "$result3"

그러나 할당이 서브쉘에서 수행되기 때문에 이는 작동하지 않습니다.

디스크의 출력 파일을 리디렉션할 수 있습니다.

pipeline | number | one > result1 &
pipeline | number | two > result2 &
pipeline | number | three > result3 &

wait

printf 'Result 1: %s\n' "$(<result1)"
printf 'Result 2: %s\n' "$(<result2)"
printf 'Result 3: %s\n' "$(<result3)"

하지만 임시 파일을 만드는 것도 피하고 싶습니다.

read또한 다양한 작업에 및 를 사용해 보았지만 coproc문제는 항상 그 read또는 var=$()블록인 것 같습니다.

임시 파일을 생성하지 않고 bash가 여러 명령의 출력을 비동기적으로 캡처하도록 하는 방법이 있습니까?

답변1

parset당신은 (GNU Parallel의 일부) 를 찾고 있습니다 .

parset result1,result2,result3 'pipeline | number | {}' ::: one two three

parset수년간 현장 테스트를 거친 GNU Parallel을 기반으로 구축되었습니다. 따라서 출력에 \n, 공백, TAB, * 또는 이와 유사한 내용이 포함되어 있으면 (가끔 발생하는) 불쾌한 예상치 못한 경쟁 조건에 직면할 가능성이 줄어들고 문제가 발생할 가능성도 줄어듭니다.

예시 1:

. env_parallel.bash
env_parallel --session
pipeline() { seq 100; }
number() { perl -pe 's/^/Foo: /'; }
one() { grep 1; }
two() { grep 2; }
three() { grep 3; }
env_parset result1,result2,result3 'pipeline | number | {}' ::: one two three
env_parallel --end-session
echo "$result3"

예 2:

. env_parallel.bash
pipeline() { seq 100; }
number() { perl -pe 's/^/Foo: /'; }
one() { grep 1; }
two() { grep 2; }
three() { grep 3; }
export -f pipeline number one two three
parset result1,result2,result3 'pipeline | number | {}' ::: one two three
echo "$result3"

(GNU 병렬하다임시 파일을 생성하지만 예상치 못한 충돌이 발생하더라도 파일을 정리하기 위해 최선을 다합니다.

답변2

세 가지 명령이 실행됩니다. 우리는 어느 쪽이 낙오자가 될지 모릅니다.

당신은 (대략) 이런 일이 일어나기를 원한다고 말했습니다.

one    &
two    &
three  &
wait

문제는 이것이 세 줄의 출력을 생성하고 모두 무작위 순서로 뒤섞여 있다는 것입니다.

이것은 어려운 문제처럼 들리지 않습니다. 각 출력 라인을 표시하면 됩니다.

( one   | sed -l 's/^/1 /' &
  two   | sed -l 's/^/2 /' &
  three | sed -l 's/^/3 /' &
) |
  sort -nk1 --stable |
  sed 's/^[123] //'

이제 올바른 순서로 편리하게 배치할 수 있는 세 줄의 출력을 구문 분석해야 합니다. 필요에 따라 변수에 할당합니다.

관련 정보