it-swarm-ko.tech

bash에서 이중 대괄호와 단일 대괄호의 차이점은 무엇입니까?

방금 차이점이 정확히 무엇인지 궁금했습니다.

[[ $STRING != foo ]]

[ $STRING != foo ]

후자는 posix를 준수하고 sh에서 발견되고 전자는 bash에서 발견되는 확장입니다.

451
0x89

몇 가지 차이점이 있습니다. 제 생각에는 가장 중요한 몇 가지는 다음과 같습니다.

  1. [은 Bash와 다른 많은 현대 쉘에 내장되어 있습니다. 내장 []의 추가 요구 사항이있는 test와 유사합니다. 내장 [test 기능은 /bin/[/bin/test 기능을 제한하여 스크립트가 이전 버전과 호환되도록합니다. 원본 실행 파일은 여전히 ​​대부분 POSIX 호환 및 이전 버전과의 호환성을 위해 존재합니다. Bash에서 type [ 명령을 실행하면 [이 기본적으로 내장으로 해석됨을 나타냅니다. (참고 : which [ PATH 에서 실행 파일 만 찾고 type -p [과 같습니다.
  2. [[은 (는) 호환되지 않으므로 /bin/sh이 (가) 가리키는 것이 무엇이든 반드시 작동하지는 않습니다. 따라서 [[은 더 현대적인 Bash/Zsh/Ksh 옵션입니다.
  3. [[은 셸에 내장되어 있으며 레거시 요구 사항이 없으므로 IFS 에 따라 Word 분할에 대해 걱정할 필요가 없습니다. = 변수는 공백이있는 문자열로 평가되는 변수를 엉망으로 만듭니다. 따라서 변수를 큰 따옴표로 묶을 필요는 없습니다.

대부분의 경우 나머지는 더 좋은 구문입니다. 더 많은 차이점을 보려면이 링크를 FAQ 답변)에 연결하는 것이 좋습니다. 테스트와 [[? 의 차이점은 무엇입니까? bash 스크립팅에 대해서는 FAQ, Pitfalls 및 Guide를 포함하여 wiki 전체를 읽는 것이 좋습니다. 가이드 섹션의 테스트 섹션 이식성에 대해 걱정할 필요가없는 경우 [[이 더 나은 선택이라고 생각하는 이유는 다음과 같습니다.

  1. 테스트의 왼쪽을 따옴표로 묶어 실제로 변수로 읽도록 걱정할 필요는 없습니다.
  2. 입력 리디렉션으로 평가되지 않도록 백 슬래시로 < >보다 작거나 이스케이프 할 필요가 없습니다. 파일을 덮어 써서 일부 내용을 엉망으로 만들 수 있습니다. 이것은 다시 내장 된 [[으로 돌아갑니다. [(test)가 외부 프로그램 인 경우, 쉘은 <을 호출하는 경우에만 >/bin/test을 평가하는 방식에서 예외를 만들어야합니다. 실제로 말이되지 않습니다.
325
Kyle Brandt

한마디로 :

[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

138
abhiomkar

행동 차이

Bash 4.3.11과의 차이점 :

  • POSIX vs Bash 확장 :

  • 정규 명령 대 마법

    • [는 이상한 이름을 가진 일반적인 명령입니다.

      ]는 추가 인수가 사용되지 않도록하는 [의 인수 일뿐입니다.

      Ubuntu 16.04는 실제로 coreutils에서 제공하는 /usr/bin/[에 실행 파일이 있지만 bash 내장 버전이 우선합니다.

      Bash가 명령을 구문 분석하는 방식에는 아무런 변화가 없습니다.

      특히 <는 리디렉션이며 &&||는 여러 명령을 연결하며 ( )\로 이스케이프하지 않으면 하위 셸을 생성하며 단어 확장 평소와 같이 발생합니다.

    • [[ X ]]X를 마술처럼 파싱하는 단일 구문입니다. <, &&, ||()가 특별하게 취급되며 단어 분리 규칙이 다릅니다.

      ==~와 같은 추가 차이점도 있습니다.

      Bashese에서 : [는 내장 명령이고, [[는 키워드입니다 : https://askubuntu.com/questions/445749/whats-the-difference-between -쉘 내장 및 쉘 키워드

  • <

  • &&||

    • [[ 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과 같은 경우)에 실패하고 ab는 십진 정수처럼 보입니다. 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, ltgt를 사용하고 비교를 위해 이중 괄호를 사용하여 ==, !=, <,> 말 그대로.

  • [는 테스트 명령의 동의어입니다. 쉘에 내장되어 있어도 새로운 프로세스를 생성합니다.
  • [[는 개선 된 새로운 버전으로, 프로그램이 아니라 키워드입니다.

예를 들면 다음과 같습니다.

[ var1 lt var2] #works
[ var1 < var2] #error: var2 No such file or directory 
[ var1 \< var2] #works with escape
[[ var1 < var2]] #works
6
Premraj

맨 페이지의 관련 섹션을 빠르게 읽었을 때 가장 큰 차이점은 ==!= 연산자는 리터럴 문자열이 아닌 패턴과 일치하며 =~ 정규식 비교 연산자.

4
womble