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 확장 :
[
POSIX입니다[[
https://www.gnu.org/software/bash/manual/bash.html#Conditional-Constructs에 설명 된 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 < b ]]
: 사전 비교[ a \< b ]
: 같은 상기와.\
필요하거나 다른 명령과 마찬가지로 리디렉션을 수행합니다. 배쉬 확장.expr a \< b > /dev/null
: POSIX에 상응하는 ², 다음을 참조하십시오 : Bash에서 사전 사전 이하의 문자열 테스트 방법?
&&
과||
[[ 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 [ ] )
'Programing' 카테고리의 다른 글
AngularJ에서 CORS를 활성화하는 방법 (0) | 2020.06.20 |
---|---|
Eclipse에서 전체 프로젝트를 찾거나 바꾸는 방법이 있습니까? (0) | 2020.06.20 |
브라우저 창 닫기 이벤트를 캡처하는 방법은 무엇입니까? (0) | 2020.06.20 |
상속 vs. 집계 (0) | 2020.06.20 |
Clojure에서 목록 위에 벡터를 사용해야하는 경우와 다른 방법은 무엇입니까? (0) | 2020.06.20 |