사용자 입력으로 배열 값을 읽으면 배열 길이가 잘못되고 -a 또는 -p만 읽기에 작동합니다.

사용자 입력으로 배열 값을 읽으면 배열 길이가 잘못되고 -a 또는 -p만 읽기에 작동합니다.

질문 1: 런타임 시 사용자 입력으로 배열 항목을 가져오고 항목을 인쇄하고 배열 길이를 인쇄하고 싶습니다. 이것이 내가 가진 것입니다:

read -a myarray
echo "array items" ${myarray[@]}
echo "array length" ${#myarray[@]}

실행하는 동안 다음을 입력으로 제공했습니다.

$ ("apple fruit" "orange" "grapes")

출력은,

array items "apple fruit" "orange" "grapes"
array length 4

이것은 정확하지 않습니다.

사용자 입력을 요청하지 않고 코드의 일부로 선언되고 초기화된 배열을 사용하면 myarray=("apple fruit" "orange" "grapes")배열 길이가 3으로 에코됩니다. 그래서 읽기 명령을 잘못 사용하고 있는 것 같습니다.

질문 2: 아래와 같이 읽기 명령에 프롬프트를 추가하면,

read -p "enter array items: " myarray

첫 번째 항목 "사과 열매"가 "과일"로 인쇄되어 있으며 길이도 잘못되었습니다.

프롬프트를 제거하고 -a를 추가하면 모든 것이 정상입니다. a와 p를 결합하여 read -ap로 지정하면 프롬프트가 전혀 표시되지 않습니다. 값을 기다리지만 메시지는 없습니다. 왜 그럴까요? 누군가 나에게 무엇이 잘못되었는지 설명해 줄 수 있습니까?

답변1

질문 1:

귀하의 예에서 read입력은 명령줄 인수가 아니라 표준 입력에서 가져옵니다. 따라서 수신하는 입력은 bash문자열 구문 분석기를 통과하지 않습니다 . 대신 공백으로 구분된 리터럴 문자열로 처리됩니다. 따라서 입력에 따라 배열 값은 다음과 같습니다.

[0]->("apple
[1]->fruit"
[2]->"orange"
[3]->"grapes"

원하는 작업을 수행하려면 구분 기호가 적용되지 않도록 모든 공백을 이스케이프 처리해야 합니다. 즉, 호출 후에 다음을 입력해야 합니다 read.

apple\ fruit oranges grapes

read질문 2: 수신된 입력을 배열로 저장 하려면 -a스위치 뒤에 배열 이름이 와야 합니다. 따라서 다음이 필요합니다.

read -a myarray -p "Enter your items"

답변2

쉘의 명령줄 구문 분석기는 큰따옴표와 작은따옴표에 관심을 가지지만 read그렇지 않습니다(그래서 둘 중 하나를 제거하지 않습니다). 입력 하려면 read백슬래시가 필요합니다.

apple\ fruit orange grapes

답변3

사용자가 요소를 구분하기 위해 쉘 따옴표를 사용하도록 하려면(뿐만 아니라 backslash) zsh다음을 수행할 수 있습니다.

IFS= read -r 'string?Please enter the elements: '
array=("${(@XQ)${(z)string}}")
  • (z)$string이는 쉘 파서와 같은 요소로 분할됩니다.
  • Q결과 단어에서 첫 번째 수준 참조를 제거합니다.
  • X구문으로 오류 메시지 보고
  • @빈 요소를 저장하려면 따옴표를 사용하세요.

이 방법으로 사용자는 다음을 입력할 수 있습니다.

'first word' "second word" third\ word $'word\nwith\nnewline' ''

확장이 수행되지 않더라도 예상되는 쉘 코드 구문은 따옴표로 제한되지 않습니다. 예를 들어 는 단일 단어 $(foo bar)로 구문 분석되어 구문 오류가 발생합니다. 사용자는 이를 , 또는 "${unknown"으로 입력해야 합니다.$(foo bar)${unclosed'$(foo)' 'bar)'

관련 정보