답변:
의 차이 [[ … ]]
와는 [ … ]
주로 덮여있다 배쉬 - 단일 또는 이중 브라켓을 사용 . 결정적으로, [[ … ]]
특별한 문법이지만 [
, 명령에 대한 재미있는 이름입니다. [[ … ]]
내부에 대한 특별한 구문 규칙이 [ … ]
있습니다.
와일드 카드 주름이 추가되면 다음과 같이 [[ $a == z* ]]
평가됩니다.
[[ … ]]
조건식 주위의 조건부 구문 $a == z*
입니다.==
피연산자 $a
와 및를 가진 2 진 연산자 z*
입니다.a
.==
연산자를 평가하십시오 . 변수 값이 a
pattern과 일치 하는지 테스트하십시오 z*
.[ $a == z* ]
평가 방법 은 다음과 같습니다 .
[
단어를 평가에 의해 형성되는 인수 명령 $a
, ==
, z*
, ]
.$a
변수 값으로 확장하십시오 a
.a
의 6 문자 스트링 foo b*
(예에 의해 수득 a='foo b*'
) 및 (상기 현재 디렉토리의 파일 목록 bar
, baz
, qux
, zim
, zum
), 그 팽창의 결과는 단어의 다음 목록은이 : [
, foo
, bar
, baz
, ==
, zim
, zum
, ]
.[
이전 단계에서 얻은 매개 변수로 명령 을 실행하십시오 .
[
명령은 구문 오류를 불평하고 상태 2를 리턴합니다.참고 : [[ $a == z* ]]
3 단계에서의 값은 a
단일 단어가 예상되는 상황 (조건부 연산자의 왼쪽 인수)이므로 단어 분할 및 파일 이름 생성을 거치지 않습니다 ==
. 대부분의 경우 단일 단어가 해당 위치에서 의미가있는 경우 변수 확장은 큰 따옴표처럼 작동합니다. 그러나 해당 규칙에는 예외가 있습니다. in [[ abc == $a ]]
의 값에 a
와일드 카드 가 포함 된 a
경우 와일드 카드 패턴과 일치합니다. 의 값이 예를 들어, a
인 a*
다음 [[ abc == $a ]]
사실이다 (와일드 카드 때문에 *
의 인용 부호가 확장에서 오는 $a
일치 *
) 반면 [[ abc == "$a" ]]
(거짓 일반 문자 때문에*
의 인용 된 확장에서 온 $a
것이 일치하지 않습니다 bc
). 내부는 [[ … ]]
큰 따옴표는, 변화를하지 않는 문자열 일치 연산자의 오른쪽에 제외 ( =
, ==
, !=
및 =~
).
[
test
명령 의 별명입니다 . 유닉스 버전 6에는 if
명령이 있었지만, 버전 7 (1979) 에는 if-then-else-elif-fi 구문을 포함하여 몇 가지 프로그래밍 구문이 포함 된 새로운 Bourne 쉘 이 제공 되었으며 Unix 버전 7 은 대부분의 명령을 추가했습니다 . 이전 버전 의 명령 으로 수행 된 "테스트" .test
if
[
은 별칭으로 test
만들어졌으며 둘 다 Unix System III (1981)의 쉘에 내장되었습니다 . 비록 일부 유닉스 변종은 [
그 이후 로 명령 이 없었 습니다sh
( 2000 년 초까지 Almquist 쉘을 기반으로하는 일부 BSD에서 ( 기본적으로test
항상 ash
소스 에 포함되어 있지만 BSD는 처음에 비활성화되었습니다)).
참고 test
일명 [
"테스트"를 수행하는 명령이다는 항등 연산자는 그래서 그래서, 과제와 평등 운영자들 사이를 명확하게 할 이유가 없다, 그 명령을 수행한다는 과제가 없습니다 =
. ==
은 최근의 일부 구현에서만 지원되며 [
의 별칭 일뿐 =
입니다.
때문에 [
아무것도 더 많은 명령 이상을하지 않습니다, 그것은 쉘에 의해 다른 명령과 동일한 방식으로 구문 분석됩니다.
구체적으로, 귀하의 예에서 $a
인용되지 않았기 때문에 일반적인 단어 분리 규칙에 따라 여러 단어로 나뉘어지며 각 단어는 파일 이름 생성을 일으켜 더 많은 단어로 이어질 수 있습니다. [
명령에 대한 별도의 인수 .
마찬가지로으로 z*
시작하는 현재 디렉토리의 파일 이름 목록으로 확장됩니다 z
.
경우에 따라서 예를 들어, $a
이다 b* = x
,하고있다 z1
, z2
, b1
그리고 b2
현재 디렉토리에있는 파일의 [
명령 (9 개) 인수를 얻을 것입니다 : [
, b1
, b2
, =
, x
, ==
, z1
, z2
와 ]
.
[
인수를 조건식으로 구문 분석합니다. 이 9 개의 인수는 유효한 조건식에 합산되지 않으므로 아마도 오류를 반환 할 것입니다.
이 [[ ... ]]
구조는 ksh86a
1987 년에 Korn 쉘에 의해 도입되었는데, 1987 년 ksh88
에는 처음부터 가지고 있었지만 없었습니다.
ksh (모든 구현) 외에도 [[...]]
bash (버전 2.02부터)와 zsh에서도 지원되지만, 세 가지 구현은 서로 다르며 변경 사항은 일반적으로 이전 버전과 호환 가능하지만 동일한 쉘의 각 버전마다 차이가 있습니다 (bash의 예외는 주목할만한 예외입니다) =~
동작이 변경 될 때 특정 버전 후에 몇 개의 스크립트를 중단하는 것으로 알려진 연산자). [[...]]
POSIX 또는 Unix 또는 Linux (LSB)에 의해 지정되지 않았습니다. 포함을 몇 번 포함하는 것으로 간주되었지만 주요 쉘에서 지원하는 공통 기능으로 이미 [
명령 및 case-in-esac
구성에 포함되어 있기 때문에 포함되지 않았습니다 .
전체 [[ ... ]]
구조는 명령을 구성합니다. 즉, 종료 상태 (조건부 표현식을 평가 한 결과 가장 중요한 자산 임)가 있으며 다른 명령으로 파이프 할 수 있으며 (유용하지는 않지만) 일반적으로 원하는 위치에 사용할 수 있습니다. 쉘 명령이므로 쉘 내에서만 다른 명령을 사용하지만 일반적인 간단한 명령처럼 구문 분석되지 않습니다. 내부는 조건식으로 쉘에 의해 구문 분석 되며 일반적인 단어 분할 및 파일 이름 생성 규칙이 다르게 적용됩니다.
[[ ... ]]
==
처음부터 알고 있으며 =
1 과 같습니다 . ksh의 혼란은 (그리고 혼란과 많은 버그를 유발하고 있습니다) =
and ==
는 등호 연산자가 아니라 패턴 일치 연산자입니다 (하지만 일치하는 측면은 인용 부호로 비활성화 할 수 있지만 쉘마다 다른 명확한 규칙으로 비활성화 할 수는 있음).
위의 코드 [[ $a == z* ]]
에서 쉘은 일반적인 토큰과 비슷한 규칙으로 여러 토큰으로 구문 분석하고 패턴 일치 비교로 인식 z*
하며 a
변수 의 내용과 일치하는 패턴으로 처리 합니다.
일반적으로 명령 [[ ... ]]
보다 발로 자신을 쏘기가 더 어렵습니다 [
. 그러나 같은 몇 가지 규칙
-a
or -o
연산자를 사용하지 마십시오 (여러 [
명령 &&
및 ||
셸 연산자 사용)확인 [
POSIX 쉘과 신뢰성.
[[...]]
다른 쉘 -nt
에서는 정규 표현식 일치 연산자와 같은 추가 연산자를 지원 하지만 목록과 동작은 쉘마다, 버전마다 다릅니다.
따라서 스크립트가 해석 할 쉘 및 최소 버전을 모른다면 표준 [
명령 을 사용하는 것이 더 안전 할 것입니다 .
1 예외 : [[...]]
version의 bash에 추가되었습니다 2.02
. 2.03
변경이 [[ x = '?' ]]
있을 때까지 true를 [[ x == '?' ]]
반환하고 false를 반환합니다 . 즉, 인용은 =
해당 버전 에서 연산자를 사용할 때 패턴 일치를 방해하지 않지만를 사용할 때 따옴표로 묶었습니다 ==
.
[ '!' = foo -o a = a ]
에서 bash
예를 들어.
둘 다 표현식을 평가하는 데 사용되며 [[POSIX 이전 버전의 쉘에서는 작동하지 않으며 패턴 일치 및 정규식도 지원합니다. 예를 들어보십시오
[ $n -eq 0 -a $y -eq 0 ] && echo "Error" || echo "Ok"
[[ $n -eq 0 && $y -eq 0 ]] && echo "Error" || echo "Ok"
[[...]]
일부 버전의 [
정규 표현식 일치 와 마찬가지로 일부 쉘의 일부 버전에서만 정규 표현식을 지원합니다. 수학적 비교를 위해을 지원하는 쉘 [[
에서 다음과 같이 작성하십시오(( n == 0 && y == 0))