병렬화하려는 여러 파이프라인이 포함된 스크립트가 있습니다. 현재는 다음과 같습니다.
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] //'
이제 올바른 순서로 편리하게 배치할 수 있는 세 줄의 출력을 구문 분석해야 합니다. 필요에 따라 변수에 할당합니다.