readarray (또는 파이프) 문제


19

나는 이상한 readarray명령 행동을 고수했다 .

man bash상태 :

readarray
     Read lines from the standard input into the indexed array variable array

그러나이 스크립트는 작동하지 않습니다 (배열이 비어 있습니다).

unset arr; (echo a; echo b; echo c) | readarray arr; echo ${#arr[@]}
unset arr; cat /etc/passwd | readarray arr;  echo ${#arr[@]}

그리고이 작품들 :

unset arr; readarray arr < /etc/passwd ;  echo ${#arr[@]}
unset arr; mkfifo /tmp/fifo; (echo a; echo b; echo c) > /tmp/fifo & mapfile arr < /tmp/fifo ; echo ${#arr[@]}

파이프에 어떤 문제가 있습니까?

답변:


15

어쩌면 시도하십시오 :

unset arr
printf %s\\n a b c | {
    readarray arr
    echo ${#arr[@]}
}

나는 그것이 효과가있을 것으로 기대하지만 파이프 라인 의 끝에서 마지막 {; }컨텍스트에서 벗어나 |면 변수 값을 잃게됩니다. 파이프 라인 내의 |개별 |프로세스가 각각 서브 쉘 |에서 실행 되기 때문 입니다. 따라서 같은 이유로 작동하지 않습니다.()

( arr=( a b c ) ) ; echo ${arr[@]}

...하지 않습니다-변수 값은 호출 한 것과 다른 쉘 프로세스 에서 설정되었습니다 .


23

readarray현재 쉘에서 명령이 실행 되도록하려면 파이프 라인 대신 프로세스 대체를 사용하십시오.

readarray arr < <( echo a; echo b; echo c )

또는 bash4.2 이상인 경우 lastpipe쉘 옵션을 사용하십시오 .

shopt -s lastpipe
( echo a; echo b; echo c ) | readarray arr

1
멋있는. 이것은 작동하지만 프로세스 대체는 정확히 무엇입니까? 그리고 < <2 개의 화살 이 있다는 것은 무엇을 의미 합니까?
CMCDragonkai

1
참고 항목 bashman 페이지를. 간단히 말해 파이프 라인을 파일 디스크립터로 취급하기위한 구문입니다. 내부 명령의 출력에서 < <(...)입력 (첫 번째 <) 을 리디렉션하는 것을 의미합니다 <(...). Similary는 > >(...)파이프 라인 내부의 표준 입력 표준 출력을 전달할 것이다 >(...). 프로세스 대체와 함께 반드시 리디렉션을 사용할 필요는 없습니다. cat <( echo a b c )잘 작동합니다.
chepner

이 두 옵션 모두 바람직하지 않은 결과를 낳습니다. 각 배열 항목은 각 문자열 끝에 줄 끝을 유지합니다. smac89의 대답에는이 문제가 없습니다.
thnee

3

readarray stdin에서 읽을 수도 있습니다.

readarray arr <<< "$(echo a; echo b; echo c)"; echo ${#arr[@]}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.