[ vs [[: bash 스크립트에서 어떤 것을 사용할까요? [복사]

[ vs [[: bash 스크립트에서 어떤 것을 사용할까요? [복사]

zsh 매뉴얼 페이지는 test(일명 [) 섹션에서 이 항목을 사용하지 말 것을 명시적으로 권고하고 독자가 [[가능할 때마다 이를 사용하도록 권장합니다.

이것관련 부품상태:

이 명령은 POSIX 및 지정된 확장을 구현하려고 시도합니다. 불행하게도 구문에는 본질적인 모호성이 있습니다. 특히 테스트 연산자와 유사한 문자열 간에는 차이가 없습니다. 표준은 소수의 매개변수(최대 4개) 문제를 해결하려고 시도합니다. 5개 이상의 매개변수에 대해서는 호환성을 신뢰할 수 없습니다. [[가능할 때마다 이러한 모호성이 존재하지 않는 경우 " " 테스트 구문을 사용하도록 사용자에게 권장합니다 .

비슷한 bash 조언을 본 것 같지만 bash 매뉴얼 페이지를 살펴봤을 때 [어떤 형식(또는 )을 사용할지에 대한 "공식적인" 조언을 찾을 수 없었습니다. [[(아마 내가 놓쳤던 것 아닐까?)

이유가 있나요?"오래된 쉘"과의 하위 호환성 외에도[, bash 스크립트에 사용됩니까? 아니면 다른 이유로 bash가 [지속 됩니까?[[다른이전 버전과의 호환성보다?

답변1

그러나 여전히 몇 가지 미묘한 차이점이 있습니다.

#!/bin/bash

eg=whatever

if [ $eg == what* ]; then   # file glob test
    echo '[]'
fi

if [[ $eg == what* ]]; then   # pattern match test
    echo "[[]]"
fi      

현재 디렉터리에 "whatever"라는 파일이 없으면 첫 번째 테스트는 현재 디렉터리 내용의 파일 glob과 일치하기 때문에 통과하지 못하는 반면, 두 번째 테스트는 실제 문자열 패턴 일치이기 때문입니다.

답변2

[충분한 경우를 선호하는 이유는 다양한 bash 버전에서 더 안정적 [[이기 때문입니다 .[

바라보다 man bash:

31과 호환 가능

설정된 경우 bash는 버전 3.1의 [[ 조건부 명령에 있는 =~ 연산자의 인용된 인수로 동작을 변경합니다.

32와 호환 가능

설정된 경우 bash는 [[ 조건부 명령의 < 및 > 연산자를 사용할 때 로케일별 문자열 비교와 관련하여 동작을 버전 3.2의 동작으로 변경합니다. bash-4.1 이전의 Bash 버전은 ASCII 조합과 strcmp(3)를 사용하고, bash-4.1 이후 버전은 현재 로케일의 조합 순서와 strcoll(3)을 사용합니다.

40과 호환 가능

설정된 경우 bash는 [[ 조건부 명령(이전 항목 참조)의 < 및 > 연산자와 명령 목록 중단 효과를 사용할 때 버전 4.0의 로케일별 문자열 비교로 동작을 변경합니다.

어쩌면 배경이 있는 사용자에게 더 일반적일 수도 있습니다 ksh.

성능에 관한 참고 사항

'[['는 '['보다 빠릅니다.

  • 단일 통화의 경우 속도 차이는 다음과 같습니다.비교할 만한 영향이 없음, 내장된 "["를 선호해야 합니다.
  • 더 큰 루프 구조에 있는 경우 '['를 '[['로 바꾸는 것을 고려할 수 있습니다.

측정을 위해 다음 비교 스크립트를 사용할 수 있습니다.

let upperBound=$1
echo "check [,  ${upperBound} iterations"
let i=0
time while [ $i -lt ${upperBound} ] ; do let i++ ; done

echo; echo;
echo "check [[, ${upperBound} iterations"
let i=0
time while [[ $i < ${upperBound} ]] ; do let i++ ; done

스크립트 결과 비교

확인[,1000회 반복

실제 0m0.031s
사용자 0m0.028s
시스템 0m0.004s

[[, 1000회 반복 확인

실제 0m0.000s
사용자 0m0.000s
시스템 0m0.000s

관련 정보