Programming

Bash의 대괄호 []보다 이중 대괄호 [[]]가 선호됩니까?

procodes 2020. 2. 12. 23:45
반응형

Bash의 대괄호 []보다 이중 대괄호 [[]]가 선호됩니까?


동료는 최근 코드 검토 에서 구조가 다음과 같은 구조 [[ ]]보다 선호되어야 한다고 주장했습니다.[ ]

if [ "`id -nu`" = "$someuser" ] ; then 
     echo "I love you madly, $someuser"
fi

그는 근거를 제시 할 수 없었다. 하나 있습니까?


[[놀라움이 적고 일반적으로 사용하는 것이 더 안전합니다. 그러나 이식성이 없습니다. POSIX는 수행하는 작업을 지정하지 않으며 일부 쉘 만 지원합니다 (bash 외에도 ksh도 지원한다고 들었습니다). 예를 들어, 할 수 있습니다

[[ -e $b ]]

파일이 있는지 테스트합니다. 그러나에 [, 당신은 인용이 $b는 인수를 분할하고 같은 일을 확장하기 때문에, "a*"(여기서 [[문자 그대로 소요). 그것은 또한 [외부 프로그램이 될 수있는 방법 과 관련이 있으며 일반적으로 다른 모든 프로그램과 마찬가지로 일반적으로 인수를받습니다 (그러나 내장 프로그램 일 수는 있지만 여전히이 특별한 처리는 없습니다).

[[=~C와 같은 언어로 알려진 연산자 함께 정규 표현식 일치와 같은 다른 멋진 기능 도 있습니다. 여기에 좋은 페이지가 있습니다 : 테스트 [의 차이점은 무엇입니까 [[? 배쉬 테스트


행동 차이

Bash 4.3.11과의 차이점 :

  • POSIX vs Bash 확장 :

  • 정규 명령 대 마법

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

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

      우분투 16.04는 실제로 coreutils/usr/bin/[제공 하는 실행 파일을 가지고 있지만 bash 내장 버전이 우선합니다.

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

      특히, 경로 <재 지정이며 여러 명령을 연결 &&하고로 이스케이프하지 않는 한 서브 쉘을 생성 하며 단어 확장은 평소와 같이 수행됩니다.||( )\

    • [[ X ]]X마술처럼 파싱 하는 단일 구문입니다. <, &&, ||()특수 처리, 워드 분할 규칙이 다릅니다된다.

      같은 더 차이도있다 =하고 =~.

      Bashese에서 : [내장 명령이며 [[키워드입니다 : https://askubuntu.com/questions/445749/whats-the-difference-between-shell-builtin-and-shell-keyword

  • <

  • &&||

    • [[ a = a && b = b ]]: 진실하고 논리적 이며
    • [ 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 상당
  • 확장시 단어 분리 및 파일 이름 생성 (분할 + 글로브)

    • x='a b'; [[ $x = 'a b' ]]: 따옴표가 필요하지 않습니다.
    • 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?글로브가 확장됩니다. 따라서 현재 디렉토리의 파일에 따라 true 또는 false 일 수 있습니다.
    • [ ab = a\? ]: false, glob 확장이 아님
    • ===모두 동일 [하고 [[있지만, ==배쉬 확장입니다.
    • case ab in (a?) echo match; esac: POSIX 상당
    • [[ ab =~ 'ab?' ]]: 거짓 ⁴, 마법을 잃는다 ''
    • [[ ab? =~ 'ab?' ]]: 진실
  • =~

    • [[ 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 쉘 의 동등한 구성에서 영감을 받음

² 그러나 a또는 b(와 같은 +또는 index) 의 일부 값에는 실패하고 10 진수 정수 a같으면 숫자 비교를 수행합니다 b. expr "x$a" '<' "x$b"둘 다 해결합니다.

³도의 일부 값 실패 ab같은 !(.

⁴ 떠들썩한 파티 3.2 이상 3.1 배시에 제공 상용 성 (와 같이 사용할 수 없습니다 BASH_COMPAT=3.1)

shell 쉘 연산자 ( 연산자 또는 / 연산자 반대 )가 동일한 우선 순위를 갖기 때문에 그룹화 (여기서 {...;}명령 그룹을 사용 (...)하여 불필요한 서브 쉘을 실행 함)는 필요하지 않습니다 . 따라서 동일합니다.||&&||&& [[...]]-o-a [[ a = a ] || [ a = b ] && [ a = b ]


[[ ]]더 많은 기능이 있습니다. 자세한 내용은 Advanced Bash Scripting Guide 를 참조하십시오. 특히 7 장의 확장 된 테스트 명령 섹션을 참조하십시오 .

또한, 가이드 노트로서 [[ ]]ksh88 (1988 년 Korn 쉘)에 도입되었습니다.


에서 어떤 비교, 테스트, 브래킷 또는 이중 브라켓, 빠른입니까? ( http://bashcurescancer.com )

이중 괄호는“복합 명령”으로, 테스트와 단일 괄호는 쉘 내장입니다 (실제로 같은 명령). 따라서 단일 괄호와 이중 괄호는 다른 코드를 실행합니다.

테스트 및 단일 브래킷은 별도의 외부 명령으로 존재하므로 가장 이식성이 뛰어납니다. 그러나 원격으로 최신 버전의 BASH를 사용하는 경우 이중 괄호가 지원됩니다.


[[autotools configure.ac 스크립트에 있습니다. 대괄호에는 특수하고 다른 의미가 있으므로 []를 사용할 수없는 일반적인 상황이므로 test[또는 [[-대신 test와 [ .


Google 스타일 가이드 를 따르는 경우 :

테스트, [및 [[

[[와]]와 [[...]] 사이에 경로 이름 확장이나 단어 분리가 발생하지 않기 때문에 [[...]]는 오류를 줄입니다. [...]가 아닌 정규 표현식 일치가 가능합니다.

# This ensures the string on the left is made up of characters in the
# alnum character class followed by the string name.
# Note that the RHS should not be quoted here.
# For the gory details, see
# E14 at https://tiswww.case.edu/php/chet/bash/FAQ
if [[ "filename" =~ ^[[:alnum:]]+name ]]; then
  echo "Match"
fi

# This matches the exact pattern "f*" (Does not match in this case)
if [[ "filename" == "f*" ]]; then
  echo "Match"
fi

# This gives a "too many arguments" error as f* is expanded to the
# contents of the current directory
if [ "filename" == f* ]; then
  echo "Match"
fi

[[]] 이중 괄호는 특정 버전의 SunOS에서 지원되지 않으며 다음과 같이 함수 선언 내부에서 완전히 지원되지 않습니다. GNU bash, 버전 2.02.0 (1)-릴리스 (sparc-sun-solaris2.6)


간단히 말해서, [[다른 프로세스를 포크하지 않기 때문에 더 좋습니다. 다른 프로세스를 분기하기 때문에 대괄호 나 단일 대괄호는 이중 대괄호보다 느립니다.

참고 URL : https://stackoverflow.com/questions/669452/is-double-square-brackets-preferable-over-single-square-brackets-in-ba



반응형