ZSH에서 배열 첨자로 나타날 수 있는 산술 표현식은 무엇입니까?

ZSH에서 배열 첨자로 나타날 수 있는 산술 표현식은 무엇입니까?

ZSH 매뉴얼( zshparam(1))의 내용은 다음과 같습니다.

Array Subscripts
       Individual elements of an array may be selected using a subscript.  A
       subscript of the form `[exp]' selects the single element exp, where
       exp is an arithmetic expression which will be subject to arithmetic
       expansion as if it were surrounded by `$((...))'.

그러나 이는 빠르게 실패합니다.

mc% arr=(a b c d e)     
mc% echo $arr[$#arr]    
e
mc% echo $arr[$(($#arr))]
e
mc% echo $arr[$(($#arr - 1))]
d
mc% echo $arr[$#arr - 1]  
zsh: invalid subscript

질문:왜? 예외는 무엇입니까?

노트:이 문제는 다음에서 비롯됩니다.don_crissti님의 답변이 있습니다., 그들은 $arr[RANDOM % $#arr + 1]임의의 요소에 액세스할 것을 제안하지만 이로 인해 위의 오류가 발생합니다.

답변1

기술적으로 모든 표현식은 아래 첨자로 표시될 수 있습니다. 문제는 파서가 원하는 것을 아래 첨자에 넣도록 하는 것입니다. 일부 문자(공백 포함)는 나타나지 않습니다. 아래 첨자는 단어의 일부이므로 단어 구성 문자만 아래 첨자의 일부가 될 수 있습니다.

mc% echo $arr[ 1]       
zsh: invalid subscript
mc% echo $arr[1 ]
zsh: invalid subscript
mc% echo $arr[$#arr - 1]
zsh: invalid subscript
mc% echo $arr[$#arr-1]
d

아래 첨자 파서는 첫 번째 잘못된 문자에서 멈추고 zsh가 종료 닫는 괄호를 확인하기 전에 "잘못된 아래 첨자" 오류가 발생합니다.

mc% echo $arr[ 1  
zsh: invalid subscript

에서 echo $arr[ 1]공백 뒤의 부분은 실제로 별도의 단어로 간주됩니다. echo및 확장의 결과인 두 인수가 수신되지만 구문 분석이 실패하기 때문에 zsh는 명령 실행을 시작하지 않습니다. 어떤 경우에는 산술 표현식의 일부라고 생각하는 내용이 실제로는 다음과 같이 구문 분석되지 않는 것을 볼 수 있습니다. 예를 들면 다음과 같습니다.$arr[1]

mc% echo $arr[1<<2]   
heredoc> << is a heredoc operator, not part of the subscript.
heredoc> 2]
zsh: invalid subscript

물론 단어를 형성하지 않는 문자는 산술 표현식이나 명령 대체와 같은 중첩된 확장의 일부로 몰래 들어올 수 있습니다.

mc% echo $arr[$[1&3]] 
a
mc% echo $arr[`echo "1 + 2"`]  
c

인수 확장에 큰따옴표를 사용하는 경우 모든 문자(균형 닫는 괄호 또는 닫는 따옴표 제외)는 아래 첨자의 일부가 됩니다. 이는 큰따옴표 안의 모든 문자가 실제로 단어를 만드는 문자이기 때문입니다. 마찬가지로, 매개변수 확장이 중괄호를 사용하는 경우, zsh는 }아래 첨자의 닫는 중괄호를 찾기 전에 매개변수 확장의 닫는 중괄호를 찾습니다. ]따라서 단어를 구성하지 않는 문자는 아래 첨자로 들어갑니다.

mc% echo "$arr[$#arr - 1]"
d
mc% echo ${arr[$#arr - 1]}
d

구체적인 내용을 알아보고 싶다면 관련 기능은 다음과 같습니다.parse_subscript, 다음에서 전화함getindex.

관련 정보