ㅏ

변수를 역참조할 때는 기호를 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)
    

    여기서 st는 모두 피연산자입니다. 피연산자는 함수에 전달됩니다.

    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 ]] 

여기서 문자열 ( x6)도 비교되며 서로 다릅니다.

x=6
[[ x = 6 ]]

그러나 이는 변수를 확장하므로 이는 사실입니다.

x=6
[[ $x = 6 ]]

답변3

예, 귀하의 관찰이 정확합니다. 이중 괄호 아래의 표현식에서 변수 확장이 수행되므로 변수 이름 앞에 [[ ]]넣을 필요가 없습니다 .$

이는 매뉴얼에 명확하게 명시되어 있습니다 bash.

[[ 표현하다]]

(...) [[와 ]] 사이의 단어에 대해서는 단어 분리 및 경로 이름 확장이 수행되지 않습니다. 물결표 확장, 매개변수 및 변수 확장, 산술 확장, 명령 대체, 프로세스 대체 및 따옴표 제거가 수행됩니다.

이는 단일 대괄호 버전의 경우에는 해당되지 않습니다 [ ]. [이는 쉘 키워드(구문)가 아니라 명령(bash에서는 내장되어 있고 다른 쉘에서는 테스트를 위해 외부, 인라인을 사용할 수 있음)이기 때문입니다.

관련 정보