[[ $a == z* ]]와 [ $a == z* ]의 차이점은 무엇입니까?

[[ $a == z* ]]와 [ $a == z* ]의 차이점은 무엇입니까?

둘 사이에 차이가 있나요?

[[ $a == z* ]]

그리고

[ $a == z* ] 

서로 다른 출력이 나오는 예를 들어봐도 될까요?

[[ ]]또한 어떻게 다르게 작동합니까 [ ]?

답변1

[[ … ]]와 의 차이점은 [ … ]주로 다음에 반영됩니다.따옴표가 없는 공백 매개변수 확장이 이중 괄호 "[[" 내에서는 작동하지만 단일 괄호 "[" 내에서는 작동하지 않는 이유는 무엇입니까?. 중요한 것은 [[ … ]]특별한 구문이 [아니라 . [[ … ]]내부 내용에 대한 특별한 문법 규칙 은 없습니다 [ … ].

와일드카드를 추가한 후 [[ $a == z* ]]계산은 다음과 같습니다.

  1. [[ … ]]구문 분석 명령: 조건식에 대한 조건부 구성 입니다 $a == z*.
  2. 조건식 구문 분석: ==피연산자가 $asum 인 이항 연산자입니다 z*.
  3. 첫 번째 피연산자를 변수 값으로 확장합니다 a.
  4. 평가 ==연산자: 변수 값이 a패턴과 일치 하는지 테스트합니다 z*.
  5. 조건식을 평가합니다. 결과는 조건 연산자의 결과입니다.
  6. 이제 명령이 평가되고 조건식이 true이면 상태가 0이고 조건식이 false이면 1입니다.

[ $a == z* ]평가방법은 다음과 같습니다.

  1. Parse 명령: , , [단어를 평가하여 인수가 형성된 명령 입니다 $a.==z*]
  2. $a변수의 값으로 확장됩니다 a.
  3. 명령 매개변수에 대해 단어 분할 및 파일 이름 생성을 수행합니다.
    • 예를 들어, 값이 a6자 문자열 foo b*(예: 를 통해 얻음 a='foo b*')이고 현재 디렉터리의 파일 목록이 ( bar, baz, qux, zim, zum)인 경우 확장 결과는 다음 단어 목록입니다: [, foo, bar,,, ,,, .baz==zimzum]
  4. [이전 단계에서 얻은 매개변수를 사용하여 명령을 실행합니다.
    • 위 예제 값의 경우 [명령은 구문 오류에 대해 불평하고 상태 2를 반환합니다.

참고: [[ $a == z* ]]3단계에서 값은 a단일 단어가 예상되는 컨텍스트에 있기 때문에 단어 분할 및 파일 이름 생성에 사용되지 않습니다(조건 연산자의 왼쪽 매개 변수 ==). 대부분의 경우 변수 확장은 개별 단어가 해당 위치에서 의미가 있는 경우 큰따옴표 안에 있는 것처럼 동작합니다. 그러나 이 규칙에는 예외가 있습니다. 에서는 [[ abc == $a ]]값에 a와일드카드 문자가 포함되어 있으면 abc와일드카드 패턴과 비교됩니다. 예를 들어, ais의 값이 a*true ( 인용된 확장의 [[ abc == $a ]]와일드카드 문자가 와 일치하기 때문에 )이고 값이 false(인용된 확장의 일반 문자가 일치하지 않기 때문에)인 경우입니다. 내부에서 큰따옴표는 아무런 차이가 없습니다.*$abc[[ abc == "$a" ]]*$abc[[ … ]]문자열 일치 연산자의 오른쪽에 추가로( =, ==, !=그리고 =~).

답변2

[는 명령의 별칭입니다 test. 유닉스 버전 6에는if명령이 있지만 버전 7(1979)에는 새로운 명령이 포함되어 있습니다.본 쉘몇 개나 있나요?프로그램 작성구문에는 if-then-else-elif-fi 구문이 포함되며 Unix 버전 7이 추가되었습니다.testif이 명령은 이전 버전에서 이 명령으로 수행된 대부분의 "테스트"를 수행합니다.

[별칭으로 사용되었으며 test둘 다 Unix System III(1981) 셸에 내장되었습니다.. 일부 Unix 변형 [에는 훨씬 나중에까지 명령이 없다는 점에 유의해야 합니다 (2000년대 초반까지 일부 BSD는 shAlmquist 쉘을 기반으로 했습니다.( test내장 기능은 항상 ash소스 코드에 포함되어 있었지만 이러한 BSD에서는 처음에 비활성화되었습니다.)

testaka 는 할당을 수행하지 않는 "테스트"를 수행하는 명령 이므로 [할당 연산자와 항등 연산자, 즉 항등 연산자를 구분할 이유가 없습니다 =. ==일부 최근 구현에서만 지원됩니다 [(별칭으로만 =).

[이는 명령일 뿐이므로 쉘은 이를 다른 명령과 동일하게 구문 분석합니다 .

특히, 귀하의 예에서 $a는 인용되지 않았기 때문에 일반적인 단어 분할 규칙에 따라 여러 단어로 분할되고 각 단어는 파일 이름 생성(일명 globbing)을 거쳐 가능한 더 많은 단어를 생성합니다. 각 단어는 다음에 대한 별도의 인수를 생성합니다. 명령 [.

마찬가지로 z*현재 디렉토리로 확장됩니다 z.

예를 들어, $a현재 디렉토리에 , 및 파일 이 b* = x있는 경우 명령은 , , , , , 및 9개의 매개변수를 가져옵니다.z1z2b1b2[[b1b2=x==z1z2]

[인수를 조건식으로 구문 분석합니다. 이러한 9개 매개변수는 유효한 조건식을 합산하지 못하므로 오류를 반환할 수 있습니다.

[[ ... ]]구성은 아마도 아래와 같이 1988년경 Korn 쉘에 의해 도입되었을 것입니다.ksh86a1987년에는 존재하지 않았지만 ksh88태초부터 존재해왔습니다.

ksh(모든 구현) 외에도 [[...]]bash(버전 2.02부터) 및 zsh도 지원되지만 세 가지 구현이 모두 다르며 동일한 셸의 각 버전 간에 차이가 있습니다. 그러나 이러한 변경 사항은 일반적으로 Post-호환을 지향합니다. ( =~특정 버전 이후 동작이 변경되면 일부 스크립트를 중단시키는 것으로 알려진 bash는 주목할만한 예외입니다 .) [[...]]POSIX, Unix 또는 Linux(LSB) 지정되지 않았습니다. 여러 차례 포함이 고려되었지만 주요 셸에서 지원하는 공통 기능이 이미 명령 [및 구문에서 다루어졌기 때문에 포함되지 않았습니다.case-in-esac

전체 [[ ... ]]구조가 명령을 구성합니다. 즉, 종료 상태(조건식을 평가한 결과이기 때문에 가장 중요한 자산)가 있어 다른 명령으로 파이프할 수 있으며(비록 쓸모는 없지만) 일반적으로 다음을 사용하여 필요할 때마다 사용합니다. 다른 모든 명령(쉘 구성이기 때문에 쉘 내부에서만 가능), 일반 단순 명령처럼 구문 분석되지 않습니다. 내부 콘텐츠가 구문 분석됩니다.쉘을 통해조건식으로는 단어 분할 및 파일 이름 생성에 대한 공통 규칙이 다르게 적용됩니다.

[[ ... ]]처음부터 알려져 있으며 1== 과 동일합니다 . ksh의 한 가지 버그(혼동과 많은 버그로 이어지는)는 동등 연산자 가 아니라 패턴 일치 연산자입니다(비록====성냥측면은 참조로 비활성화할 수 있지만 규칙은 명확하지 않으며 셸마다 다릅니다.

위의 코드에서 [[ $a == z* ]]쉘은 이를 일반적인 규칙과 유사한 규칙의 몇 가지 토큰으로 구문 분석하고 이를 패턴 일치 비교로 인식하고 이를 z*변수의 내용과 일치하는 패턴 으로 처리합니다 a.

[[ ... ]]일반적으로 명령을 내리는 것보다 발에 총을 쏘는 것이 더 어렵습니다 [. 하지만 다음과 같은 몇 가지 규칙이 있습니다.

  • 항상 참조 변수
  • -aor 연산자를 사용하지 마십시오 -o(여러 [명령을 사용 &&하고|| 껍데기운영자)

[POSIX 쉘을 사용하여 안정성을 향상시키십시오.

[[...]]추가 연산자는 다른 셸에서 지원됩니다(예 -nt: 정규식 일치 연산자...). 그러나 목록과 동작은 셸과 버전에 따라 다릅니다.

따라서 스크립트가 해석될 셸과 최소 버전을 알지 않는 한 [표준 명령을 사용하는 것이 더 안전할 것입니다.


1한 가지 예외: [[...]]버전의 bash에 추가되었습니다 2.02. 2.03변경되기 전까지 는 [[ x = '?' ]]true가 반환되고 [[ x == '?' ]]false가 반환됩니다. 즉, =이러한 버전에서 연산자를 사용할 때는 인용으로 인해 패턴 일치가 방지되지 않지만 를 사용할 때는 그렇습니다 ==.

답변3

둘 다 표현식을 평가하는 데 사용됩니다. [[는 POSIX 이전 bourn 쉘에서는 작동하지 않습니다. [[ 또한 패턴 일치 및 정규 표현식도 지원합니다. 다음 예를 시도해 보세요.

[ $n -eq 0 -a $y -eq 0 ] && echo "Error" || echo "Ok"

[[ $n -eq 0 && $y -eq 0 ]] && echo "Error" || echo "Ok"

관련 정보