변수를 역참조할 때는 기호를 bash
사용해야 합니다 $
. 그럼에도 불구하고 다음은 잘 작동하는 것 같습니다.
x=5
[[ x -gt 2 ]]
누구든지 이것을 설명할 수 있나요?
편집: (추가 정보)
내 말은 [[ ]] 명령이 $ 기호 없이 내 변수 x를 역참조하는 방법과 이유를 의미합니다. 예, x=1이면 명령문은 false로 평가됩니다(상태 1을 반환함).
답변1
그 이유는 -eq
매개변수의 산술적 평가를 강제하기 위한 것입니다.
산술 연산자: -eq
, -gt
, 및 내부적으로(ksh, zsh 및 bash에서) 변수 이름이 C에서처럼 자동으로 확장되며 선행이 필요하지 않음을 -lt
의미 합니다.-ge
-le
-ne
[[ ]]
$
이를 확인하려면 bash 소스 코드를 살펴봐야 합니다. 설명서에는 제공되지 않음직접확인하다.
산술 연산자의 처리는
test.c
내부적으로 이 함수에 속합니다.arithcomp (s, t, op, flags)
여기서
s
및t
는 모두 피연산자입니다. 피연산자는 함수에 전달됩니다.l = evalexp (s, &expok); r = evalexp (t, &expok);
이 함수는 다음 헤더를 사용하여
evalexp
내부적으로 정의됩니다 .expr.c
/* expr.c -- arithmetic expression evaluation. */
그렇습니다. 산술 연산자의 양쪽 모두 (직접적으로) 산술 표현식 평가에 속합니다. 직접적이고, 하지만, if는 없습니다.
실제로,:
$ x=3
둘 다 실패합니다.
$ [[ x = 4 ]] && echo yes || echo no
no
$ [[ x = 3 ]] && echo yes || echo no
no
이는 정확하고 x
확장되지 않았으며 x
숫자와 동일하지 않습니다.
하지만:
$ [[ x -eq 3 ]] && echo yes || echo no
yes
$ [[ x -eq 4 ]] && echo yes || echo no
no
명명된 변수는 x
확장됩니다($ 없이도).
이는 zsh나 bash에서는 발생하지 않습니다 […]
(ksh에서는 발생함).
이는 내부에서 발생하는 것과 동일한 일입니다 $((…))
.
$ echo $(( x + 7 ))
10
그리고 이것은 (매우) 재귀적이라는 점을 이해하시기 바랍니다(대시 및 yash 제외).
$ a=b b=c c=d d=e e=f f=3
$ echo "$(( a + 7 ))"
10
ㅏ
답변2
숫자 비교 의 피연산자 -eq
, -gt
, -lt
, -ge
및 는 산술 표현식으로 처리됩니다. 일부 제한으로 인해 여전히 단일 쉘 단어여야 합니다.-le
-ne
산술 표현식에서 변수 이름의 동작은 다음에 설명되어 있습니다.쉘 산술:
쉘 변수는 피연산자로 허용됩니다. 매개변수 확장은 표현식 평가 전에 수행됩니다.표현식 내에서 쉘 변수는 매개변수 확장 구문을 사용하지 않고도 이름으로 참조될 수도 있습니다.null이거나 설정되지 않은 쉘 변수는 매개변수 확장 구문을 사용하지 않고 이름으로 참조할 때 0으로 평가됩니다.
그리고:
변수의 값은 참조될 때 산술 표현식으로 평가됩니다.
하지만 실제로 숫자의 비교에는 산술 표현식이 필요하다는 문서의 일부를 찾을 수 없습니다. 설명 없음조건부 구조아래 [[
에 설명되어 있지도 않습니다.Bash 조건식.
그러나 실험을 통해 위와 같이 작동하는 것으로 보입니다.
따라서 다음과 같은 것이 유효합니다.
a=6
[[ a -eq 6 ]] && echo y
[[ 1+2+3 -eq 6 ]] && echo y
[[ "1 + 2 + 3" -eq 6 ]] && echo y
이것은 또한 (변수의 값을 평가하는 것):
b='1 + 2 + 3'
[[ b -eq 6 ]] && echo y
그러나 그렇지 않습니다. 구문 분석할 때 단일 쉘 단어가 아니므 [[ .. ]]
로 조건에 구문 오류가 있습니다.
[[ 1 + 2 + 3 -eq 6 ]] && echo y
다른 산술 컨텍스트에서는 표현식에 공백이 없어야 할 필요는 없습니다. 이는 999
괄호가 인덱스의 산술 표현식을 명확하게 구분하기 때문에 인쇄됩니다 .
a[6]=999; echo ${a[1 + 2 + 3]}
반면에 =
비교는패턴 매칭, 산술 컨텍스트에서 수행되는 산술 또는 자동 변수 확장(조건부 구성)을 포함하지 않습니다.
==
and 연산자를 사용할 때!=
연산자 오른쪽의 문자열은 패턴으로 처리되며 마치 extglob 쉘 옵션이 활성화된 것처럼 패턴 일치에 설명된 규칙에 따라 일치됩니다. 연산자는=
와 동일합니다==
.
문자열이 분명히 다르기 때문에 이것은 잘못된 것입니다.
[[ "1 + 2 + 3" = 6 ]]
이는 값이 동일하더라도 마찬가지입니다.
[[ 6 = 06 ]]
여기서 문자열 ( x
및 6
)도 비교되며 서로 다릅니다.
x=6
[[ x = 6 ]]
그러나 이는 변수를 확장하므로 이는 사실입니다.
x=6
[[ $x = 6 ]]
답변3
예, 귀하의 관찰이 정확합니다. 이중 괄호 아래의 표현식에서 변수 확장이 수행되므로 변수 이름 앞에 [[ ]]
넣을 필요가 없습니다 .$
이는 매뉴얼에 명확하게 명시되어 있습니다 bash
.
[[ 표현하다]]
(...) [[와 ]] 사이의 단어에 대해서는 단어 분리 및 경로 이름 확장이 수행되지 않습니다. 물결표 확장, 매개변수 및 변수 확장, 산술 확장, 명령 대체, 프로세스 대체 및 따옴표 제거가 수행됩니다.
이는 단일 대괄호 버전의 경우에는 해당되지 않습니다 [ ]
. [
이는 쉘 키워드(구문)가 아니라 명령(bash에서는 내장되어 있고 다른 쉘에서는 테스트를 위해 외부, 인라인을 사용할 수 있음)이기 때문입니다.