에서 간단한 수학 연산을 수행하면 #!/bin/sh
하위 쉘이 생성됩니까?
예를 들어,
addition=$(( 1 + 1 ))
구문에서는 하위 쉘 사용을 제안하지만 이에 대해 아무것도 찾을 수 없습니다.
답변1
$(cmd arg)
서브셸 환경에서 실행하면 cmd
해당 출력(후행 줄 바꿈 제외)이 확장된 결과가 됩니다.
(cmd arg)
서브쉘에서 실행되지만 출력은 영향을 받지 않습니다.
따라서 extra subshell 과 동일 $((cmd arg))
하지만 그렇지 않습니다.$(cmd arg)
$((...))
Korn 쉘과 별도의 확장입니다. Korn 쉘에서는 ((arithmetic expression))
산술 표현식이 평가되고(구문은 C의 구문과 매우 유사함) 종료 상태는 표현식이 0 또는 0이 아닌 것으로 확인되는지 여부를 반영합니다.
이를 통해 다음과 같은 작업이 가능해집니다.
if ((var < 10)); then
...
fi
이것 은 그것 을 매우 비슷하게 보이게 합니다 C
.
$
소개를 위해확장하다. 그거 빼고는 $(cmd)
비슷 해요(cmd)
확장하다출력은 그것을 제외 cmd
하고 $((arith))
는 같습니다((arith))
확장하다산술 표현식의 평가 결과입니다.
sh
대부분 ksh88을 기반으로 하는 POSIX는 지정되어 있지만 $((...))
지정되지는 않았습니다 ((...))
. 사실 초기 초안에서는 그 $[...]
반대를 의도한 것이었는데, 그래서 찾아내고 bash
대체품 으로 zsh
지원하게 된 거죠 .$[...]
$((...))
IIRC, POSIX가 처음에 이를 지정하는 것을 고려한 주된 이유 $[...]
는 명령 대체 내의 하위 쉘과의 충돌 때문이었습니다 $((...))
.$((cmd arg))
$((echo x; echo y) | (tr xy ab))
대부분의 쉘은 다음과 같이 올바르게 식별됩니다 .아니요산술 확장은 $((cmd arg))
확장 의 출력이 아니라 변수의 산술 값 $((cmd))
으로 확장됩니다 .$cmd
cmd
POSIX 사양의 관련 텍스트는 다음과 같습니다.
쉘 명령 언어의 구문은 "$(("로 시작하는 확장과 관련하여 모호합니다. 이는 산술 확장 또는 하위 쉘로 시작하는 명령 대체를 도입할 수 있습니다. 산술 확장이 우선합니다. 즉, 쉘은 먼저 다음 사항을 결정해야 합니다. 확장은 산술 확장으로 해석될 수 있으며, 끝이 발견될 때만 산술 확장으로 확장을 해석할 수 없다고 판단하는 경우 쉘은 중첩된 확장을 평가할 필요가 없습니다. 불완전한 산술 확장을 처리하고 구문 오류를 보고합니다. 적합한 응용 프로그램은 "$(" 및 '(.them)을 구분해야 합니다. 예를 들어 단일 하위 쉘과 관련된 명령 대체는 다음과 같이 작성할 수 있습니다.
ksh
또한 ((...))
중첩된 하위 쉘과 충돌합니다. POSIX는 이를 지정하지 않지만 ((...))
ksh의 동작을 허용합니다.
실제로 하위 쉘 및/또는 cmdsubst를 중첩할 때 대괄호 사이에 공백을 포함해야 합니다.
echo "$( (...) )"
( (a; b) | (c;d) )
답변2
이것은 데모입니다아니요서브셸에서 실행: 산술 표현식에서 변수를 수정할 수 있습니다.
$ x=5; echo "$(( x *= 2 ))"; echo "$x"
10
10
서브쉘인 경우 echo $x
이것이 출력됩니다 5
.
쉘 산술을 사용할 때, 모든 쉘이 증가를 지원하는 것은 아닙니다( dash
현재 버전의 데비안과 그 파생 버전의 기본값)는 변수를 증가시키는 것이 아니라 해석됩니다./bin/sh
$(( ++i ))
$(( +(+i) ))
i