Bash에서 [[ ]] AND [ ] 또는 (( )) AND ( )의 차이점

Bash에서 [[ ]] AND [ ] 또는 (( )) AND ( )의 차이점

[[ condition ]]이들 그리고 [ condition ]또는 (( condition ))그리고 를 사용하는 것의 차이점은 무엇인가요 ( condition )? 어떤 시나리오에서 이들 중 하나를 사용해야 합니까?

  • (( 10 > 9 ))작동하지만 (( 10 -gt 9 ))작동하지 않습니다
  • [[ 10 -gt 9 ]]작동하지만 [[ 10 > 9 ]]작동하지 않습니다

답변1

((...))껍질의 것입니다산수건설하다. 사용할 수 있는 연산자는 설명서에 설명되어 있습니다.6.5 쉘 산술

(...)그룹화서브셸에 포함된 명령을 실행하는 구성:3.2.4.3 그룹화 명령

[...]"레거시" 조건부 구성입니다. 문서는 다음 위치에 있습니다.6.4 Bash 조건식

[[...]]할 일은 다 합니다 [...]. 차이점은 내부 변수에 대해 단어 분할 및 전역 확장이 수행되지 않으므로 [[...]]변수를 인용하는 것이 그다지 중요하지 않다는 것입니다. 추가적으로 [[할 수 있는 일패턴 매칭운영자 님 ==정규식 일치운영자 와 함께 =~.

[[ 10 > 9 ]]예상치 못한 결과가 나오는 이유 는 >내부의 연산자 [[...]]문자열 비교문자열 "10"은 문자열 "9"보다 "작습니다".

답변2

정보 ((…))(…)

에 명시된 바와 같이이 다른 답변((…))쉘의 산술 구조입니다(a바시즘) (…)서브쉘에서 명령을 실행합니다. 그것들은 서로 매우 다르며 [ … ]또는 와도 매우 다릅니다 [[ … ]].

반면에 [ … ]간단한 [[ … ]]경우에는 매우 유사합니다. 그들은 혼란스러울 수 있습니다. 이 답변의 나머지 부분은 [ … ]및 에 집중합니다 [[ … ]].


공식 메모

내 목표는 다음과 같습니다.

  • 자세히 설명하다[ … ]와 의 차이점과 유사점[[ … ]];
  • [ … ]vs 주제에 대한 정식 답변을 제공하기 위해 " is not " [[ … ]]로 답변할 수 있는 질문을 여기에 연결할 수 있습니다.[[[
  • 충분히 철저한 답변을 제공하므로 사용자는 더 이상 각각의 단일 차이점에 초점을 맞춘 답변을 게시하려는 유혹을 느끼지 않습니다.

무엇인가요 [?

  1. [테스트를 수행합니다.

    의 목적은 [무언가(예: 파일이 존재하는 경우)를 테스트하고 테스트에 성공하면 종료 상태 0을 반환하고 그렇지 않으면 0이 아닌 값을 반환하는 것입니다.

  2. [명령이다.

    [cat또는 같은 명령 이름입니다 echo. [(like echo)는 Bash에 내장되어 있지만 이는 추가 프로세스를 생성하지 않고도 실행할 수 있다는 의미일 뿐이며 여전히 명령처럼 작동합니다. [시스템에 독립 실행형 실행 파일이 있을 수 있습니다 (예 /bin/[: ). type -a [Bash를 사용해 알아보세요 .

  3. [뒤에 공백이 필요합니다.

    명령으로 [인수를 사용합니다. 다른 명령과 마찬가지로 인수는 명령 이름과 서로 분리되어야 합니다. [foo은 다른 명령 이름이므로 와 동일하지 않습니다 [ foo(비슷하고 더 명백하게 echoHello world는 가 아닙니다 echo Hello world). 뒤에는 반드시 공백(또는 탭)이 필요합니다 [.

  4. [필요합니다 ].

    []마지막 인수로 요구합니다 . 그렇지 않으면 작동을 거부합니다. 이는 [ … ]마치 특별한 구문인 것처럼 블록으로 눈에 띄게 만들기 위한 것입니다. 하지만 특별한 구문은 아닙니다. 마지막 인수로 전달하려면 ]그 앞에 공백(또는 탭)이 필요합니다. 비교를 위해 의 마지막 인수는 [ … bar]which bar]is not ]이므로 [ … bar]유효한 명령이 아닙니다.

  5. [(거의) 와 같습니다 test.

    [ … ]와 같습니다 test …. 즉, 명령 이름을 제거 하고 변경하여 모든 [명령을 명령으로 변환할 수 있습니다. 그리고 명령 이름 을 변경하고 .test]test[]

  6. [특별하지 않습니다.

    기억해 두는 것이 좋습니다. [특별한 것은 아니며 단지 명령에 대한 다소 화려한 이름일 뿐입니다. 이 사실을 인정한다면, 그 사실에 놀라지 않을 것입니다.모두쉘을 구문 분석하고 처리하는 것은~ 전에명령( test또는 echols)을 실행하는 것은 명령이 이면 발생합니다 [. 특히:

    • [인수 중 하나를 인용했는지 여부를 인식하지 못하고 쉘이 인용부를 제거한 후에 인수를 얻습니다.

    • 따옴표가 없고 이스케이프되지 않거나 &&||사이는 []대한 인수로 해석되지 않습니다 [. 즉 은 (가 없기 때문에 유효하지 않음 ) 및 (별도의 명령이 무엇 이든) 와 정확히 와 논리적으로 연결된 [ … || … ]것으로 해석됩니다 .[ …]… ]||command1 || command2

  7. [POSIX에 의해 지정됩니다.

    거기에는[/ 에 대한 POSIX 사양test. 휴대용 으로 전화할 수 있습니다 [. 노트:

    • 일부 기본은 확장이고 일부는 더 이상 사용되지 않는 것으로 표시됩니다. 예를 들어 유효하지 않은 코드( [ … || … ])는 로 수정될 수 있지만 더 이상 사용되지 [ … -o … ]않으므로 -o더 나은 수정은 입니다 [ … ] || [ … ].
    • 구현에서는 더 많은 기본을 지원할 수 있습니다. [Bash의 내장 기능은 이를 수행합니다(참고자료 참조 ) help test. OS의 바이너리(예: )가 있을 수 있습니다( 참조 [) ./bin/[man test

무엇인가요 [[? 와 어떻게 [[다른 가요 [?

참고 사항:
- 질문에 태그가 지정되었습니다., 지금 우리가 얘기하고 있는 건[[ 배쉬에서.
- 이 섹션의 번호가 매겨진 단락은 이전 섹션의 번호가 매겨진 단락과 일치합니다.

  1. (유사성)[[테스트를 수행합니다.

    의 목적은 [[무언가(예: 파일이 존재하는 경우)를 테스트하고 테스트에 성공하면 종료 상태 0을 반환하고 그렇지 않으면 0이 아닌 값을 반환하는 것입니다. [[무엇이든 테스트할 수 있습니다 [.

  2. (차이점)[[키워드입니다.

    [[​는 쉘 키워드 입니다 type [[이를 확인하려면 Bash에서 호출하세요). [내장 과 마찬가지로 [[키워드도 Bash에 속합니다. 하지만 그것은하지 않습니다명령처럼 행동하세요.

  3. (유사성)[[뒤에 공백이 필요합니다.

    (또는 탭).

  4. (유사성)[[필요합니다 ]].

    [[코드 후반부에 필요 하지만 블록으로 눈에 띄게 ]]만드는 것만은 아닙니다 . [[ … ]]이는 특별한 구문입니다(차이점에 대해 알아보겠습니다). 앞에 공백(또는 탭)이 필요합니다 ]].

  5. (차이점)에 해당하는 일반적으로 보이는 명령은 없습니다 [[.

    대체할 수 있는 [[방식으로 대체할 수 있는 다른 명령/키워드/무엇이든 없습니다 .test[

  6. (차이점)[[ ~이다특별한.

    [[쉘이 코드를 구문 분석하고 해석하는 방식을 일치하는 ]]. 셸의 일반적인 구문 분석 및 처리는 실행 전에 수행되거나 [또는 test(또는 echols)은 내부에 적용되지 않습니다 [[ … ]]. 특히:

    • [[ ~이다"인수"를 인용했는지 확인하십시오. 큰따옴표 변수는 필요하지 않습니다(일반적으로그것은), 그러나 경우에 따라 문자열(또는 변수)을 큰따옴표로 묶으면 차이가 발생합니다(참조이 답변=여기서 " 또는 또는 또는 ==의 오른쪽 "을 언급합니다.!==~

    • &&또는 구조 ||사이에 [[속하며 구성 ]]에 속합니다 [[ … ]]. [[ … || … ]]와 사실상 동등한 유효한 코드 조각일 수 있습니다 [[ … ]] || [[ … ]].

  7. (차이점)[[POSIX에 의해 지정되지 않았습니다.

    [[​휴대용 이 아닙니다 [[Bash에서는 작동하지만 pure 에서는 작동하지 않습니다 sh. 다른 쉘도 지원할 수 있지만 [[(예: Zsh는 지원) Bash의 [[쉘과 다를 수 있습니다 [[.

    [[[/ 의 사양을 따르도록 설계되지 않았습니다 test. 대부분의 경우 [with [[]with를 대체하면 원본 조각 과 동일한 조각이 ]]제공됩니다 . 하지만 항상 그런 것은 아닙니다.[[ … ]][ … ]때때로내부를 조정해야합니다. 그러니 맹목적 [으로 바꾸지 마세요 [[. 맹목적 [[으로 변경하는 것은 할 수 있지만 할 수 없는 [테스트가 있기 때문에 훨씬 더 위험합니다 .[[[


기타 참고 사항:

  1. 구문 의 일부 [도 아닙니다 . 일부 코드의 종료 상태만 테스트한다는 것을 기억하세요 . 유효합니다, 유효합니다, 유사 하거나 유효합니다( 또는 부분 자체가 유효한 조각인 경우).[[if … then …ifif true; then …if sleep 5; then …if [ … ]; then …if [[ … ]]; then …[ … ][[ … ]]

    ((…))or (…)도 일부 종료 상태(내부 내용에 따라 다름)를 반환하므로 이후에도 사용할 수 있습니다 if.

  2. 개인적으로 나는 정말 필요할 때 쉽게 수행할 수 있는 [모든 테스트에 사용하는 것을 선호합니다. 이렇게 하면 이식성이 없는 것에 익숙해지지 않고 Bash만큼 풍부하지 않은 쉘에서 무엇을 할 수 있는지 알 수 있습니다.[[[[[

  3. OS의 실행 파일 [이 반드시 [Bash의 내장 파일과 동일하지는 않습니다. Bash에 의해 호출 되면 [내장 기능이 작업을 수행합니다. 다른 것에 의해 호출 되면 [실행 파일이 작업을 수행합니다. 예를 들어 find … -exec [ … ] …실행 파일을 사용합니다. [[(적어도 내가 아는 시스템에는) 표준 실행 파일이 없으므로 find … -exec [[ … ]] …절대 작동하지 않습니다. 실행 파일이 있는 경우 [[명령처럼 작동해야 하며 키워드를 모방할 수 없습니다.

답변3

[ ]와 [[ ]] 사이에는 큰 차이가 있습니다.

a=0;
if [ $a = 1 -a $(grep ERR 1.log|wc -l) -ne 0 ];then
      echo "error";
fi 

[ ]를 사용할 때 및 연산자 -a는 단락 평가를 지원하지 않습니다. 위 코드에서는 첫 번째 조건이 false를 반환하더라도 두 번째 조건은 계속 평가됩니다. 1.log 파일이 없으면 "해당 파일이나 디렉터리가 없습니다"라는 메시지가 표시됩니다.

이 아니라면 [[ ]]:

a=0
if [[ $a = 1 && $(grep ERR 1.log|wc -l) -ne 0 ];then
    echo "error"
fi

"1.log" 파일이 존재하지 않더라도 첫 번째 조건이 false이므로 두 번째 조건은 평가되지 않으므로 괜찮습니다.

답변4

이 내용을 댓글로 달고 싶었지만 아직은 허용되지 않습니다.

[]와 [[]] 사이에서 제가 발견한 한 가지 차이점은 전자에서는 다중 비교를 사용할 수 있다는 것입니다.

동일한 비교로 [[]]에서 구문 오류가 발생합니다.

a=1
b=2

이것은 작동합니다:

$  [ "$a" -gt 0 -a "$b" -gt "$a" ] && { echo '[b>a>0]'; }
[b>a>0]

이것은 작동하지 않습니다:

$ [[ $a -gt 0 -a $b -gt $a ]] && { echo '[[b>a>0]]'; }
-bash: syntax error in conditional expression
-bash: syntax error near `-a'

왜 그런지 자세히 알아보지는 않았지만 다중 비교를 사용할 때는 []를 사용합니다.

관련 정보