티 프로세스 교체 서브셸에서 전역 변수 내보내기

티 프로세스 교체 서브셸에서 전역 변수 내보내기
command | tee >(var="$(command1)") >(var1="$(command2)")
echo "$var $var1"

또한 moreutils pee를 시도했습니다.

command | pee 'var="$(command)"' 'var1="$(command2)"' 

또한 내보내기 명령을 시도했습니다 | tee >(export var="$(command1)") >(var1="$(command2)")

질문 1 내 필요는 하나의 명령의 출력을 사용하고 이를 여러 명령의 입력으로 사용하는 것입니다.

질문 2

function() { Array=("$1"); }
function String

위의 작품

command | parallel -I %% function %%

위에서 작동하지 않는 배열이 설정되지 않은 경우 해결 방법이 있습니까? 도와주세요.

명령 출력:

1 word
2 word
3 word
4 word
1 string
2 string
3 string
4 string

두 개의 연관 배열을 어떻게 설정합니까? 하나는 단어로, 다른 하나는 파이프 출력의 문자열로 설정합니까? 배열1[1]=워드 배열1[2]=워드

배열2[1]=문자열 배열2[2]=문자열

답변1

@they가 말했듯이 프로세스 교체는 하위 쉘에서 실행되므로 해당 할당은 기본 쉘에 표시되지 않습니다. pee마찬가지이며 parallel적어도 후자는 내보낸 함수를 사용할 수 있지만 여전히 코드를 실행할 다른 셸을 시작합니다.

임시 파일을 사용할 수도 있습니다결과해결 방법으로 입력 데이터가 결과보다 긴 경우 이 방법이 유용할 수 있습니다. 예를 들어:

seq 10 | tee >(wc -l > lines) >(wc -c > chars) > /dev/null
lines=$(< lines)
chars=$(< chars)

아니면 어쩌면

tmp1=$(mktemp)
tmp2=$(mktemp)
seq 10 | tee >(wc -l > "$tmp1") >(wc -c > "$tmp2") > /dev/null
lines=$(< "$tmp1")
chars=$(< "$tmp2")
rm -f "$tmp1" "$tmp2"

답변2

표시된 코드의 외부 셸에 표시되도록 변수 값을 설정하려고 한다고 가정합니다.

표시된 모든 예제에서 변수 할당 및 export실행은 하위 쉘(또는 하위 프로세스)에서 수행됩니다. 서브셸에서는 변수가 설정되어 평소처럼 사용할 수 있습니다. 그러나 서브쉘이 종료되면 쉘 변수이든 환경 변수("내보낸 쉘 변수")이든 관계없이 변수가 손실됩니다. 하위 쉘은 상위 쉘의 환경에 영향을 미칠 수 없습니다.

여기에서 임시 파일을 사용할 수 있습니다.

some-command >tmpfile

var1=$(other-command1 <tmpfile)
var2=$(other-command2 <tmpfile)

rm -f tmpfile

또는 some-command사소한 경우(셸 내장 유틸리티만 사용하고 최소한의 리소스를 사용하며 많은 출력을 생성하지 않음):

var1=$( some-command | other-command1 )
var2=$( some-command | other-command2 )

개행으로 구분된 데이터를 배열로 읽는 작업(원하는 경우)은 readarrayin 을 사용하여 수행됩니다 bash.

readarray -t array < <( some-command )

some-command그러나 명령이 많은 출력을 생성하는 경우에는 원하는 대로 수행하지 않을 수도 있습니다. 이 경우에는 awkPython이나 다른 언어를 사용하여 파이프라인의 데이터를 처리하는 것이 좋습니다 .

답변3

parset당신이 찾고있는 --pipe --tee:

mkfifo myfifo
command > myfifo &
env_parset var,var1 --pipe --tee ::: command1 command2 < myfifo
echo "$var $var1"

예:

command() { seq 10000; }
command1() { wc -l; }
command2() { wc -c; }
mkfifo myfifo
command > myfifo &
env_parset var,var1 --pipe --tee ::: command1 command2 < myfifo
echo "$var $var1"

command1및를 command2내보내는 경우 다음을 사용할 수 있습니다 parset.

export -f command1 command2
mkfifo myfifo
command > myfifo &
parset var,var1 --pipe --tee ::: command1 command2 < myfifo
echo "$var $var1"

command1command2옵션이 다른 동일한 명령인 경우 :

command > myfifo &
parset var,var1 --pipe --tee wc {} ::: -c -l < myfifo
echo "$var $var1"

배열로 출력을 원하는 경우:

command > myfifo &
parset arr --pipe --tee wc {} ::: -c -l < myfifo
echo "${arr[0]} ${arr[1]} ${arr[2]}"

연관 배열로 출력을 원하는 경우:

typeset -A myassoc
command > myfifo &
parset myassoc --pipe --tee wc {} ::: -c -l < myfifo
echo "${myassoc[-c]} ${myassoc[-l]}"

다른 사람들이 지적했듯이 파이프를 사용하여 데이터를 / |로 파이프 할 수 없습니다. 왜냐하면 서브쉘에서 / 가 생성되기 때문입니다. 이것이 바로 FIFO 트릭이 필요한 이유입니다.parsetparallelparsetparallel

쉘에서 허용하는 경우 다음을 수행할 수도 있습니다.

typeset -A myassoc
parset myassoc --pipe --tee wc {} ::: -c -l < <(command)
echo "${myassoc[-c]} ${myassoc[-l]}"

자세한 내용은 다음을 참조하세요. https://www.gnu.org/software/parallel/parset.html

관련 정보