Programing

Bash에서 단일 및 이중 대괄호의 차이점

lottogame 2020. 6. 20. 10:45
반응형

Bash에서 단일 및 이중 대괄호의 차이점


나는 bash 예제를 읽고 if있지만 일부 예제는 단일 대괄호로 작성됩니다.

if [ -f $param ]
then
  #...
fi

이중 대괄호가있는 기타 :

if [[ $? -ne 0 ]]
then
    start looking for errors in yourlog
fi

차이점은 무엇입니까?


[]posix 쉘 호환 조건 테스트는 단일 입니다.

Double [[]]은 표준의 확장 []이며 bash 및 기타 셸 (예 : zsh, ksh)에서 지원됩니다. 추가 작업 (표준 posix 작업)을 지원합니다. 예를 들어 : ||대신 -o정규 표현식과 일치합니다 =~. 차이점에 대한 전체 목록은 조건부 구성 에 대한 bash 매뉴얼 섹션에서 찾을 수 있습니다 .

[]쉘에서 스크립트를 이식 가능하게 할 때마다 사용하십시오 . [[]]조건식을 지원 []하지 않고 이식 가능하지 않은 경우 사용하십시오 .


행동 차이

Bash 4.3.11에서 테스트 :

  • POSIX vs Bash 확장 :

  • 정규 명령 대 마법

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

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

      우분투 16.04는 실제로 /usr/bin/[coreutils 제공 하는 실행 파일을 가지고 있지만 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 상당 5
  • 확장시 단어 분할 및 파일 이름 생성 (분할 + 글로브)

    • 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? glob expands. So may be true or false depending on the files in the current directory.
    • [ ab = a\? ]: false, not glob expansion
    • = and == are the same in both [ and [[, but == is a Bash extension.
    • case ab in (a?) echo match; esac: POSIX equivalent
    • [[ ab =~ 'ab?' ]]: false4, loses magic with ''
    • [[ ab? =~ 'ab?' ]]: true
  • =~

    • [[ ab =~ ab? ]]: true, POSIX extended regular expression match, ? does not glob expand
    • [ a =~ a ]: syntax error. No bash equivalent.
    • printf 'ab\n' | grep -Eq 'ab?': POSIX equivalent (single line data only)
    • awk 'BEGIN{exit !(ARGV[1] ~ ARGV[2])}' ab 'ab?': POSIX equivalent.

Recommendation: always use [].

There are POSIX equivalents for every [[ ]] construct I've seen.

If you use [[ ]] you:

  • lose portability
  • force the reader to learn the intricacies of another bash extension. [ is just a regular command with a weird name, no special semantics are involved.

¹ Inspired from the equivalent [[...]] construct in the Korn shell

² but fails for some values of a or b (like + or index) and does numeric comparison if a and b look like decimal integers. expr "x$a" '<' "x$b" works around both.

³ and also fails for some values of a or b like ! or (.

4 in bash 3.2 and above and provided compatibility to bash 3.1 is not enabled (like with BASH_COMPAT=3.1)

5 though the grouping (here with the {...;} command group instead of (...) which would run an unnecessary subshell) is not necessary as the || and && shell operators (as opposed to the || and && [[...]] operators or the -o/-a [ operators) have equal precedence. So [ a = a ] || [ a = b ] && [ a = b ] would be equivalent.


Inside single brackets for condition test (i.e. [ ... ]), some operators such as single = is supported by all shells, whereas use of operator == is not supported by some of the older shells.

Inside double brackets for condition test (i.e. [[ ... ]]), there is no difference between using = or == in old or new shells.

Edit: I should also note that: In bash, always use double brackets [[ ... ]] if possible, because it is safer than single brackets. I'll illustrate why with the following example:

if [ $var == "hello" ]; then

if $var happens to be null / empty, then this is what the script sees:

if [ == "hello" ]; then

which will break your script. The solution is to either use double brackets, or always remember to put quotes around your variables ("$var"). Double brackets is better defensive coding practice.


[[ is a bash keyword similar to (but more powerful than) the [ command.

See

http://mywiki.wooledge.org/BashFAQ/031 and http://mywiki.wooledge.org/BashGuide/TestsAndConditionals

Unless you're writing for POSIX sh, we recommend [[.


you can use the double square brackets for light regex matching, e.g. :

if [[ $1 =~ "foo.*bar" ]] ; then

(as long as the version of bash you are using supports this syntax)


Bash manual says:

When used with [[, the ‘<’ and ‘>’ operators sort lexicographically using the current locale. The test command uses ASCII ordering.

(The test command is identical to [ ] )

참고URL : https://stackoverflow.com/questions/13542832/difference-between-single-and-double-square-brackets-in-bash

반응형