readarray (또는 파이프) 문제

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[@]} 

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

답변

시도 가능 :

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

작동 할 것으로 예상합니다. ,하지만 |<의 끝에있는 마지막 {; } 컨텍스트에서 벗어나는 순간 / div> pipeline은 변수 값을 잃게됩니다. 이는 | 파이프 라인 내의 각 | 개별 | 프로세스가 다음 위치에서 실행되기 때문입니다. ( 하위 셸 ). 따라서 동일한 이유로 작동하지 않습니다.

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

… doesn “t-변수 값이 다른 쉘 프로세스를 호출하는 것보다.

답변

readarray 명령은 파이프 라인 대신 프로세스 대체를 사용하여 현재 셸에서 실행됩니다.

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

또는 (bash 4.2 이상) lastpipe 셸 옵션 사용 :

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

댓글

  • 멋지네요. 이것은 작동하지만 프로세스 대체는 정확히 무엇입니까? 그리고 < < 2 개의 화살표가 있다는 것은 무엇을 의미합니까?
  • bash 매뉴얼 페이지를 참조하십시오. 간단히 말해서 파이프 라인을 파일 설명 자로 처리하는 '의 구문입니다. < <(...)<(...)<)을 리디렉션하는 것을 의미합니다. >. 유사하게 > >(...)는 표준 출력을 >(...) 내부 파이프 라인의 표준 입력으로 전달합니다. ' 반드시 프로세스 대체와 함께 리디렉션을 사용할 필요는 없습니다. cat <( echo a b c )도 작동합니다.
  • 이 두 옵션 모두 바람직하지 않은 결과를 생성합니다. 여기서 각 배열 항목은 각 문자열의 끝에서 줄 끝을 유지합니다. smac89의 답변에는이 문제가 없습니다.
  • readarray -t arr를 사용하여 줄 끝을 제거 할 수 있습니다. man bash : -t Remove a trailing newline from each line read.
  • '

5.0.17이고 이것은 ' 나에게 적합하지 않습니다. ' BASHOPTS도 확인했는데 lastpipe가 포함되어 있지만 cat myfile.txt | readarray -t arr는 빈 arr를 제공하지만 readarray -t arr < <(cat myfile.txt)는 올바르게 작동합니다.

Answer

readarray는 stdin에서도 읽을 수 있으므로 :

readarray arr <<< "$(echo a; echo b; echo c)"; echo ${#arr[@]} 

답글 남기기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다