Bash: 산술 확장, 매개변수 확장 및 쉼표 연산자

Bash: 산술 확장, 매개변수 확장 및 쉼표 연산자

bash, 쉼표 표현식 및 산술 표현식 내에서 매개변수 확장에 대해 질문이 있습니다. 나는 동등해야 한다고 생각하는 두 가지 진술을 가지고 있지만 그렇지 않습니다.

배쉬가 작동하는 이유

n=3; k=10; echo $((n++,k=$n))

3? 대신 출력합니다 4. (예상대로 로 설정되어 있었는데 n로 설정되어 있었습니다.)4k3

대신, bash 라인

 n=3; k=10; echo $((n++,k=n))

출력은 4예상한 대로입니다. ( n으로 설정되어 있으며 4, 로도 k설정되어 있습니다 4.)

나는 두 bash 라인에서 n++with ++n, with n=n+1및 with 를 바꾸려고 시도했지만 n=$((n+1))모두 동일한 차이를 보였습니다: 모든 스크립트에서 k=$n, 모든 스크립트에서.3k=n4


내 이해는 값이 n정수(정수) 인 경우 산술 표현식에서 동일한 값을 가져야 한다는 것입니다 $n. n(구조상 (( ... ))이것은 산술 표현식입니다.) bash 매뉴얼에 따르면 산술 평가 섹션의 산술 표현식에서:

   Shell variables are allowed as  operands;  parameter  expansion  is  performed  before  the
   expression  is  evaluated.  Within an expression, shell variables may also be referenced by
   name without using the parameter expansion syntax.

그러면 왜 bash는 $n이 예제와 다르게 이를 처리하며 n정확히 어떻게 평가됩니까 $n?


쉼표 연산자를 사용하지 않으면 문제를 재현할 수 없습니다. 내가 아는 한, 쉼표 연산자는 각 구성 요소를 평가할 때 해당 구성 요소의 모든 부작용을 포함하여 각 구성 요소 하위 표현식을 왼쪽에서 오른쪽으로 평가합니다. 쉼표 표현식의 값은 마지막으로 평가된 구성 요소(가장 오른쪽)의 값입니다.


이 질문은 좀 더 복잡한 스크립트의 맥락에서 나왔고 결국 문제를 보여주기 위해 이 간단한 예제로 범위를 좁혔습니다.

그렇다면 산술 확장, 매개변수 확장 또는 쉼표 연산자에 대해 내가 무엇을 오해하고 있습니까?

이미 해결 방법이 있으므로 해결 방법을 찾고 있는 것이 아닙니다. with 버전은 예상 n대로 작동합니다. 나는 bash가 가 포함된 버전에서 무엇을 하는지 , 왜 가 포함된 버전과 다른 기능을 수행하는지 $n알고 싶습니다 .$nn

답변1

쉘 매개변수 확장이 발생합니다.표현식을 평가하기 전에 쉼표 처리 포함:

표현식은 큰따옴표로 묶인 것처럼 처리되지만, 괄호 안의 큰따옴표는 특별히 처리되지 않습니다. 표현식의 모든 토큰은 매개변수 및 변수 확장, 명령 대체 및 따옴표 제거를 거칩니다. 결과는 평가할 산술 표현식으로 처리됩니다.

너는 이것을 볼 수 있다

unset n
echo $((n++,k=$n))

잘못된 정보,

bash: n++,k=: syntax error: operand expected (error token is "=")

$n전체 연산식이 처리되기 전에 디스플레이가 교체됩니다.

귀하의 경우 평가된 표현식은 다음과 같습니다.

n++,k=3

답변2

내부적으로 $((...))는 큰따옴표와 마찬가지로 확장이 먼저 수행된 다음 결과가 평가됩니다.

따라서 n=3; k=10; echo $((n++,k=$n))(또는 n=1; echo "$((++n + $n))"에 국한되지 않음 ,)에서 평가된 산술 표현식은 입니다 n++, k=3.

여기에는 다음이 필요합니다.

n=3; k=10; echo "$((n++,k=n))"

(산술 확장은 POSIX 셸의 다른 형태의 단어 확장과 마찬가지로 분할+글로브의 영향을 받기 때문에 따옴표도 참고하세요.)


$((hash[$key]++))1에서는 일부 쉘이 포함할 때 올바르게 처리하려고 시도 하므로 배열 및 연관 배열 호출에서 몇 가지 변경 사항을 발견할 수 있습니다.$key]

관련 정보