산술 표현식 내에서 쉼표 표현식 내부의 bash 매개변수 확장에 대한 질문이 있습니다. 나는 동등해야 한다고 생각했지만 그렇지 않은 두 가지 진술을 가지고 있습니다.
왜 bash 라인은
n=3; k=10; echo $((n++,k=$n))
3
대신에 출력 4
? ( 예상대로 로 설정되어 있는데 로 설정되어 n
있습니다 . )4
k
3
대조적으로, bash 라인은
n=3; k=10; echo $((n++,k=n))
4
예상대로 출력됩니다 . ( , n
로 설정 됩니다 .)4
k
4
n++
나는 두 bash 줄에서 with ++n
, with n=n+1
및 with 를 바꾸려고 시도했지만 n=$((n+1))
모두 동일한 불일치를 나타냅니다. 모든 스크립트에서 k=$n
생성되고 모든 스크립트에서 생성됩니다 .3
k=n
4
내 이해는 값이 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
?
쉼표 연산자를 사용하지 않고는 문제를 복제할 수 없습니다. 내가 항상 보아온 쉼표 연산자는 해당 구성 요소가 계산될 때 각 구성 요소의 모든 부작용을 포함하여 왼쪽에서 오른쪽으로 각 구성 요소 하위 표현식을 계산합니다. 쉼표 표현식의 값은 계산된 마지막 구성 요소(가장 오른쪽 구성 요소)의 값입니다.
이 질문은 훨씬 더 복잡한 스크립트의 맥락에서 발생했으며 마침내 문제를 보여주는 이 간단한 예제로 범위를 좁혔습니다.
그렇다면 산술 확장, 매개변수 확장 또는 쉼표 연산자에 대해 내가 무엇을 오해하고 있습니까?
이미 해결 방법이 있으므로 해결 방법을 찾고 있는 것이 아닙니다. n
대신 에 버전이 $n
예상대로 작동합니다. 나는 bash가 가 있는 버전에서 무엇을 하고 있는지 $n
, 왜 bash가 단지 가 있는 버전과 다른 일을 하는지 알고 싶습니다 n
.
답변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]++))
때 올바르게 처리하려고 시도하므로 배열 및 연관 배열이 호출되는 몇 가지 변형을 찾을 수 있습니다.$key
]