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