방금 차이점이 정확히 무엇인지 궁금했습니다.
[[ $STRING != foo ]]
과
[ $STRING != foo ]
후자는 posix를 준수하고 sh에서 발견되고 전자는 bash에서 발견되는 확장입니다.
몇 가지 차이점이 있습니다. 제 생각에는 가장 중요한 몇 가지는 다음과 같습니다.
[
은 Bash와 다른 많은 현대 쉘에 내장되어 있습니다. 내장 [
은 ]
의 추가 요구 사항이있는 test
와 유사합니다. 내장 [
및 test
기능은 /bin/[
및 /bin/test
기능을 제한하여 스크립트가 이전 버전과 호환되도록합니다. 원본 실행 파일은 여전히 대부분 POSIX 호환 및 이전 버전과의 호환성을 위해 존재합니다. Bash에서 type [
명령을 실행하면 [
이 기본적으로 내장으로 해석됨을 나타냅니다. (참고 : which [
은 PATH 에서 실행 파일 만 찾고 type -p [
과 같습니다.[[
은 (는) 호환되지 않으므로 /bin/sh
이 (가) 가리키는 것이 무엇이든 반드시 작동하지는 않습니다. 따라서 [[
은 더 현대적인 Bash/Zsh/Ksh 옵션입니다.[[
은 셸에 내장되어 있으며 레거시 요구 사항이 없으므로 IFS 에 따라 Word 분할에 대해 걱정할 필요가 없습니다. = 변수는 공백이있는 문자열로 평가되는 변수를 엉망으로 만듭니다. 따라서 변수를 큰 따옴표로 묶을 필요는 없습니다.대부분의 경우 나머지는 더 좋은 구문입니다. 더 많은 차이점을 보려면이 링크를 FAQ 답변)에 연결하는 것이 좋습니다. 테스트와 [[? 의 차이점은 무엇입니까? bash 스크립팅에 대해서는 FAQ, Pitfalls 및 Guide를 포함하여 wiki 전체를 읽는 것이 좋습니다. 가이드 섹션의 테스트 섹션 이식성에 대해 걱정할 필요가없는 경우 [[
이 더 나은 선택이라고 생각하는 이유는 다음과 같습니다.
< >
보다 작거나 이스케이프 할 필요가 없습니다. 파일을 덮어 써서 일부 내용을 엉망으로 만들 수 있습니다. 이것은 다시 내장 된 [[
으로 돌아갑니다. [(test)가 외부 프로그램 인 경우, 쉘은 <
을 호출하는 경우에만 >
및 /bin/test
을 평가하는 방식에서 예외를 만들어야합니다. 실제로 말이되지 않습니다.한마디로 :
[bash Builtin
[[]]는 bash입니다 키워드
키워드 : 키워드는 내장과 매우 비슷하지만 주요 차이점은 특수 구문 분석 규칙이 적용된다는 것입니다. 예를 들어, [는 bash 내장이고, [[는 bash 키워드입니다.) 그것들은 둘 다 물건을 테스트하는 데 사용되지만 [[는 내장이 아닌 키워드이므로 몇 가지 특별한 파싱 규칙을 통해 훨씬 쉽게 만들 수 있습니다.
$ [ a < b ]
-bash: b: No such file or directory
$ [[ a < b ]]
Bash는 파일 b를 명령 [a]로 경로 재 지정하려고하기 때문에 첫 번째 예제는 오류를 리턴합니다. 두 번째 예는 실제로 예상대로 수행합니다. <문자는 더 이상 File Redirection 연산자의 특별한 의미가 없습니다.
출처 : http://mywiki.wooledge.org/BashGuide/CommandsAndArguments
행동 차이
Bash 4.3.11과의 차이점 :
POSIX vs Bash 확장 :
[
POSIX[[
는 Bash 확장명 ¹입니다. https://www.gnu.org/software/bash/manual/bash.html#Conditional-Constructs정규 명령 대 마법
[
는 이상한 이름을 가진 일반적인 명령입니다.
]
는 추가 인수가 사용되지 않도록하는 [
의 인수 일뿐입니다.
Ubuntu 16.04는 실제로 coreutils에서 제공하는 /usr/bin/[
에 실행 파일이 있지만 bash 내장 버전이 우선합니다.
Bash가 명령을 구문 분석하는 방식에는 아무런 변화가 없습니다.
특히 <
는 리디렉션이며 &&
및 ||
는 여러 명령을 연결하며 ( )
는 \
로 이스케이프하지 않으면 하위 셸을 생성하며 단어 확장 평소와 같이 발생합니다.
[[ X ]]
는 X
를 마술처럼 파싱하는 단일 구문입니다. <
, &&
, ||
및 ()
가 특별하게 취급되며 단어 분리 규칙이 다릅니다.
=
및 =~
와 같은 추가 차이점도 있습니다.
Bashese에서 : [
는 내장 명령이고, [[
는 키워드입니다 : https://askubuntu.com/questions/445749/whats-the-difference-between -쉘 내장 및 쉘 키워드
<
[[ a < b ]]
: 사전 비교[ a \< b ]
: 위와 동일합니다. \
가 필요하거나 다른 명령과 마찬가지로 리디렉션을 수행합니다. 배쉬 확장.expr a \< b > /dev/null
: POSIX 동등한 ², 다음을 참조하십시오 : https://stackoverflow.com/questions/21294867/how-to-test-strings-for-lexicographic-less-than-or-equal-in- bash/52707989 # 52707989&&
및 ||
[[ a = a && b = b ]]
: true, 논리 and[ a = a && b = b ]
: 구문 오류, &&
가 AND 명령 구분 기호 cmd1 && cmd2
로 구문 분석되었습니다.[ a = a -a b = b ]
: 동일하지만 POSIX³에서 사용되지 않음[ a = a ] && [ b = b ]
: POSIX 및 해당 제품(
[[ (a = a || a = b) && a = b ]]
: 거짓[ ( a = a ) ]
: 구문 오류, ()
는 서브 쉘로 해석됩니다[ \( a = a -o a = b \) -a a = b ]
: 동일하지만 ()
는 POSIX에서 사용되지 않습니다.{ [ a = a ] || [ a = b ]; } && [ a = b ]
POSIX 상응5확장시 단어 분할 및 파일 이름 생성 (분할 + 글로브)
x='a b'; [[ $x = 'a b' ]]
: true, 따옴표가 필요하지 않습니다x='a b'; [ $x = 'a b' ]
: 구문 오류, [ a b = 'a b' ]
로 확장x='*'; [ $x = 'a b' ]
: 현재 디렉토리에 둘 이상의 파일이 있으면 구문 오류가 발생합니다.x='a b'; [ "$x" = 'a b' ]
: POSIX 상당=
[[ ab = a? ]]
: 패턴 일치 (* ? [
는 마법이므로) true입니다. 현재 디렉토리의 파일로 확장하지 않습니다.[ ab = a? ]
: a?
glob가 확장됩니다. 따라서 현재 디렉토리의 파일에 따라 true 또는 false 일 수 있습니다.[ ab = a\? ]
: false, glob 확장이 아님=
와 ==
는 [
와 [[
에서 동일하지만 ==
는 Bash 확장입니다.case ab in (a?) echo match; esac
: POSIX 해당[[ ab =~ 'ab?' ]]
: 거짓4''
와 함께 마법을 잃습니다![[ ab? =~ 'ab?' ]]
: true=~
[[ ab =~ ab? ]]
: true, POSIX 확장 정규식 일치, ?
는 확장되지 않습니다[ a =~ a ]
: 구문 오류. bash와 동등한 것은 없습니다.printf 'ab\n' | grep -Eq 'ab?'
: POSIX 상당 (한 줄 데이터 만 해당)awk 'BEGIN{exit !(ARGV[1] ~ ARGV[2])}' ab 'ab?'
: POSIX에 해당합니다. 권장 사항 : 항상 []
를 사용하십시오.
내가 본 모든 [[ ]]
구문마다 POSIX가 있습니다.
[[ ]]
를 사용하는 경우 :
[
는 이상한 이름을 가진 일반적인 명령이며 특별한 의미가 없습니다.¹ Korn Shell의 동등한 [[...]]
구성에서 영감을 얻었습니다.
² 그러나 a
또는 b
의 일부 값 (+
또는 index
과 같은 경우)에 실패하고 a
및 b
는 십진 정수처럼 보입니다. expr "x$a" '<' "x$b"
는 둘 다 해결합니다.
³ 또한 !
또는 (
와 같은 a
또는 b
의 일부 값에도 실패합니다.
4 bash 3.2 이상에서 bash 3.1과의 호환성이 제공되지 않습니다 (BASH_COMPAT=3.1
와 같이).
5 {...;}
및 (...)
셸 연산자로 그룹화 (여기서는 ||
대신 &&
명령 그룹을 사용)가 필요하지 않습니다. (||
및 &&
[[...]]
연산자 또는 -o
/-a
[
연산자와 달리) 상위. 따라서 [ a = a ] || [ a = b ] && [ a = b ]
는 동일합니다.
싱글 브라켓 즉 []
는 조건식을 포함하도록 POSIX Shell을 준수합니다.
더블 브래킷 즉 [[]]
는 표준 POSIX 버전의 확장 (또는 확장) 버전이며 bash 및 기타 셸 (zsh, ksh)에서 지원됩니다.
Bash에서는 숫자 비교를 위해 eq
, ne
, lt
및 gt
를 사용하고 비교를 위해 이중 괄호를 사용하여 ==
, !=
, <,
및 >
말 그대로.
[
는 테스트 명령의 동의어입니다. 쉘에 내장되어 있어도 새로운 프로세스를 생성합니다.[[
는 개선 된 새로운 버전으로, 프로그램이 아니라 키워드입니다.예를 들면 다음과 같습니다.
[ var1 lt var2] #works
[ var1 < var2] #error: var2 No such file or directory
[ var1 \< var2] #works with escape
[[ var1 < var2]] #works
맨 페이지의 관련 섹션을 빠르게 읽었을 때 가장 큰 차이점은 ==
및 !=
연산자는 리터럴 문자열이 아닌 패턴과 일치하며 =~
정규식 비교 연산자.