인용된 쉘 산술 확장

인용된 쉘 산술 확장

Bash와 Dash에서는 산술 확장에 따옴표를 사용하는 것이 불법입니다.

$ bash -c 'x=123;echo $(("$x"))'
bash: "123": syntax error: operand expected (error token is ""123"")
$ dash -c 'x=123;echo $(("$x"))'
dash: 1: arithmetic expression: expecting primary: ""123""

Bash는 sh로 호출될 때 동일한 오류를 발생시킵니다. 그러나 Ksh와 FreeBSD의 Bourne Shell은 다음 사항에 신경 쓰지 않습니다.

$ ksh -c 'x=123;echo $(("$x"))'
123
$ sh -c 'x=123;echo $(("$x"))'
123

~에 따르면배쉬 참조 매뉴얼:

표현식은 큰따옴표로 묶인 것처럼 처리되지만, 괄호 안의 큰따옴표는 특별히 처리되지 않습니다. 모든 토큰은...인용문 제거를 경험하게 됩니다.

(본질적으로는POSIX설명하다. )

마지막으로 Bash는 이를 다른 산술 컨텍스트(예: 조건식)와 $(( ))다르게 처리합니다 . (( ))후자는 따옴표를 사용해도 괜찮습니다.

아니면 뭔가 이해가 안가네요견적 삭제여기를 의미합니다. 그렇지 않으면 이는 이러한 쉘 구현 중 일부의 버그입니다. 전자인 경우 "따옴표 제거"란 정확히 무엇을 의미합니까? 아니면 이것은 단지 버그입니까?

답변1

이것이 잘못된 구현인지 아니면 잘못된 문서인지 혼란스럽습니다. Bash는 참조 삭제에 대해 다음과 같이 말합니다.

견적 삭제

이전 확장 후에는 위 확장 중 하나에서 발생하지 않은 따옴표가 없는 모든 문자 \, '및 가 "제거됩니다.

내 생각에 핵심은 "모두"일 것 같아요인용되지 않음단락의 모든 내용은 $(( ))큰따옴표로 묶인 것처럼 처리됩니다. 이러한 문자가 괄호 안에 있으면 모두 인용되어 기본적으로 인용 제거가 필요하지 않습니다. 예를 들어, 다른 "제거" 문자가 처리되는 방식에 유의하세요(또한 인용 문자열이 구문 분석되는 방식으로 인해 후행 공백이 어떻게 유지되는지 참고하세요).

$ echo $(( '5' ))
bash: '5' : syntax error: operand expected (error token is "'5' ")
$ echo $(( \ ))
bash: \ : syntax error: operand expected (error token is "\ ")

소스 코드를 살펴보면 코드가 수학인지 중첩된 레거시 하위 표현식인지 확인하기 위해 코드를 검색할 때 따옴표의 균형을 맞춰야 합니다 $(( )). 문자열이 산술 표현식으로 인식되면 큰따옴표로 구문 분석됩니다.모두내부 문자는 따옴표가 제거될 때까지 따옴표로 묶인 것으로 간주됩니다.

개인적으로 이것이 제가 ksh를 선호하는 이유 중 하나입니다. 특히 수학의 경우 더욱 그렇습니다. 예를 들어, 위의 작은따옴표 5를 53으로 평가되는 C 문자열로 처리합니다. man ascii이것이 왜 의미가 있는지 알아보세요. :)

관련 정보