Bash에서 기본 REPL을 구축하려고 합니다. 이 스크립트는 사용자가 실행할 디렉터리의 파일 목록을 동적으로 채웁니다.
파일 공간:
|
|\ scripts/
|| script1.sh
|| script2.sh
|
\ shell/
| shell.bashrc
| shell.desktop
shell.bashrc에서 다음 명령을 사용하여 파일 이름 배열을 가져옵니다.
readarray -d " " filenames < <(find ../bin -type f -executable)
filenames
배열을 잘 인쇄할 수 있으며 예상대로 저장되는 공백으로 구분된 문자열이 포함되어 있습니다 "script1.sh script2.sh"
.
하지만 배열의 첫 번째 요소에 액세스하려고 하면 echo ${filenames[0]}
모든 요소가 인쇄됩니다. 0이 아닌 다른 인덱스는 빈 문자열을 반환합니다.
내 bash 버전은 5.0.17이고 파일의 첫 번째 줄은 다음과 같습니다.#!/bin/bash
비슷한 결과로 다음을 시도한 후 "readarray"를 사용하도록 전환했습니다.
filenames=($(find "../bin" -type f -executable))
편집: 어리석은 해결 방법을 찾았지만 여전히 원본 게시물에 무엇이 문제인지 궁금합니다. 해결책:
readarray -d " " filenames < <(find ../bin -type f -executable)
arr=($filenames)
echo ${arr[1]}
예상대로 배열의 6번째 요소를 인쇄합니다.
답변1
기본적으로 find
출력은 줄 바꿈으로 구분됩니다. mapfile/readarray 명령에서 이를 설정 하면 -d " "
다음과 같은 결과가 나옵니다(이름이 없다고 가정).포함하다공백 문자) 모든 결과는 줄 바꿈 등 하나의 문자열로 연결됩니다. 그때 당신이 echo ${filenames[0]}
(함께인용되지 않음변수 확장 ${filenames[0]}
및 기본 space-tab-newline 값 IFS
), 쉘은 개행 문자로 분할하고 공백 1을echo
사용하여 결과를 재조립합니다 .
대신 사용
readarray -t filenames < <(find ../bin -type f -executable)
입력을 개행으로 구분된 데이터로 구문 분석하지만 저장된 요소에서 후행 개행을 제거합니다. 또는 - 더 나은 방법은 - 귀하의 bash 버전이 이를 지원한다면,
readarray -t -d '' filenames < <(find ../bin -type f -executable -print0)
개행 문자 대신 널 바이트를 사용합니다(개행 문자가 포함된 파일 이름을 포함하여 모든 합법적인 파일 이름을 안전하게 만듭니다).