[[ 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 "[[ … ]]
로 답변할 수 있는 질문을 여기에 연결할 수 있습니다.[
[[
- 충분히 철저한 답변을 제공하므로 사용자는 더 이상 각각의 단일 차이점에 초점을 맞춘 답변을 게시하려는 유혹을 느끼지 않습니다.
무엇인가요 [
?
[
테스트를 수행합니다.의 목적은
[
무언가(예: 파일이 존재하는 경우)를 테스트하고 테스트에 성공하면 종료 상태 0을 반환하고 그렇지 않으면 0이 아닌 값을 반환하는 것입니다.[
명령이다.[
cat
또는 같은 명령 이름입니다echo
.[
(likeecho
)는 Bash에 내장되어 있지만 이는 추가 프로세스를 생성하지 않고도 실행할 수 있다는 의미일 뿐이며 여전히 명령처럼 작동합니다.[
시스템에 독립 실행형 실행 파일이 있을 수 있습니다 (예/bin/[
: ).type -a [
Bash를 사용해 알아보세요 .[
뒤에 공백이 필요합니다.명령으로
[
인수를 사용합니다. 다른 명령과 마찬가지로 인수는 명령 이름과 서로 분리되어야 합니다.[foo
은 다른 명령 이름이므로 와 동일하지 않습니다[ foo
(비슷하고 더 명백하게echoHello world
는 가 아닙니다echo Hello world
). 뒤에는 반드시 공백(또는 탭)이 필요합니다[
.[
필요합니다]
.[
]
마지막 인수로 요구합니다 . 그렇지 않으면 작동을 거부합니다. 이는[ … ]
마치 특별한 구문인 것처럼 블록으로 눈에 띄게 만들기 위한 것입니다. 하지만 특별한 구문은 아닙니다. 마지막 인수로 전달하려면]
그 앞에 공백(또는 탭)이 필요합니다. 비교를 위해 의 마지막 인수는[ … bar]
whichbar]
is not]
이므로[ … bar]
유효한 명령이 아닙니다.[
(거의) 와 같습니다test
.[ … ]
와 같습니다test …
. 즉, 명령 이름을 제거 하고 변경하여 모든[
명령을 명령으로 변환할 수 있습니다. 그리고 명령 이름 을 변경하고 .test
]
test
[
]
[
특별하지 않습니다.기억해 두는 것이 좋습니다.
[
특별한 것은 아니며 단지 명령에 대한 다소 화려한 이름일 뿐입니다. 이 사실을 인정한다면, 그 사실에 놀라지 않을 것입니다.모두쉘을 구문 분석하고 처리하는 것은~ 전에명령(test
또는echo
등ls
)을 실행하는 것은 명령이 이면 발생합니다[
. 특히:[
인수 중 하나를 인용했는지 여부를 인식하지 못하고 쉘이 인용부를 제거한 후에 인수를 얻습니다.따옴표가 없고 이스케이프되지 않거나
&&
및||
사이는[
에]
대한 인수로 해석되지 않습니다[
. 즉 은 (가 없기 때문에 유효하지 않음 ) 및 (별도의 명령이 무엇 이든) 와 정확히 와 논리적으로 연결된[ … || … ]
것으로 해석됩니다 .[ …
]
… ]
…
||
command1 || command2
[
POSIX에 의해 지정됩니다.거기에는
[
/ 에 대한 POSIX 사양test
. 휴대용 으로 전화할 수 있습니다[
. 노트:- 일부 기본은 확장이고 일부는 더 이상 사용되지 않는 것으로 표시됩니다. 예를 들어 유효하지 않은 코드(
[ … || … ]
)는 로 수정될 수 있지만 더 이상 사용되지[ … -o … ]
않으므로-o
더 나은 수정은 입니다[ … ] || [ … ]
. - 구현에서는 더 많은 기본을 지원할 수 있습니다.
[
Bash의 내장 기능은 이를 수행합니다(참고자료 참조 )help test
. OS의 바이너리(예: )가 있을 수 있습니다( 참조[
) ./bin/[
man test
- 일부 기본은 확장이고 일부는 더 이상 사용되지 않는 것으로 표시됩니다. 예를 들어 유효하지 않은 코드(
무엇인가요 [[
? 와 어떻게 [[
다른 가요 [
?
참고 사항:
- 질문에 태그가 지정되었습니다.세게 때리다, 지금 우리가 얘기하고 있는 건[[
배쉬에서.
- 이 섹션의 번호가 매겨진 단락은 이전 섹션의 번호가 매겨진 단락과 일치합니다.
(유사성)
[[
테스트를 수행합니다.의 목적은
[[
무언가(예: 파일이 존재하는 경우)를 테스트하고 테스트에 성공하면 종료 상태 0을 반환하고 그렇지 않으면 0이 아닌 값을 반환하는 것입니다.[[
무엇이든 테스트할 수 있습니다[
.(차이점)
[[
키워드입니다.[[
는 쉘 키워드 입니다type [[
이를 확인하려면 Bash에서 호출하세요).[
내장 과 마찬가지로[[
키워드도 Bash에 속합니다. 하지만 그것은하지 않습니다명령처럼 행동하세요.(유사성)
[[
뒤에 공백이 필요합니다.(또는 탭).
(유사성)
[[
필요합니다]]
.[[
코드 후반부에 필요 하지만 블록으로 눈에 띄게]]
만드는 것만은 아닙니다 .[[ … ]]
이는 특별한 구문입니다(차이점에 대해 알아보겠습니다). 앞에 공백(또는 탭)이 필요합니다]]
.(차이점)에 해당하는 일반적으로 보이는 명령은 없습니다
[[
.대체할 수 있는
[[
방식으로 대체할 수 있는 다른 명령/키워드/무엇이든 없습니다 .test
[
(차이점)
[[
~이다특별한.[[
쉘이 코드를 구문 분석하고 해석하는 방식을 일치하는]]
. 셸의 일반적인 구문 분석 및 처리는 실행 전에 수행되거나[
또는test
(또는echo
등ls
)은 내부에 적용되지 않습니다[[ … ]]
. 특히:(차이점)
[[
POSIX에 의해 지정되지 않았습니다.[[
휴대용 이 아닙니다[[
Bash에서는 작동하지만 pure 에서는 작동하지 않습니다sh
. 다른 쉘도 지원할 수 있지만[[
(예: Zsh는 지원) Bash의[[
쉘과 다를 수 있습니다[[
.[[
[
/ 의 사양을 따르도록 설계되지 않았습니다test
. 대부분의 경우[
with[[
및]
with를 대체하면 원본 조각 과 동일한 조각이]]
제공됩니다 . 하지만 항상 그런 것은 아닙니다.[[ … ]]
[ … ]
때때로내부를 조정해야합니다. 그러니 맹목적[
으로 바꾸지 마세요[[
. 맹목적[[
으로 변경하는 것은 할 수 있지만 할 수 없는[
테스트가 있기 때문에 훨씬 더 위험합니다 .[[
[
기타 참고 사항:
구문 의 일부
[
도 아닙니다 . 일부 코드의 종료 상태만 테스트한다는 것을 기억하세요 . 유효합니다, 유효합니다, 유사 하거나 유효합니다( 또는 부분 자체가 유효한 조각인 경우).[[
if … then …
if
if true; then …
if sleep 5; then …
if [ … ]; then …
if [[ … ]]; then …
[ … ]
[[ … ]]
((…))
or(…)
도 일부 종료 상태(내부 내용에 따라 다름)를 반환하므로 이후에도 사용할 수 있습니다if
.개인적으로 나는 정말 필요할 때 쉽게 수행할 수 있는
[
모든 테스트에 사용하는 것을 선호합니다. 이렇게 하면 이식성이 없는 것에 익숙해지지 않고 Bash만큼 풍부하지 않은 쉘에서 무엇을 할 수 있는지 알 수 있습니다.[
[[
[[
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'
왜 그런지 자세히 알아보지는 않았지만 다중 비교를 사용할 때는 []를 사용합니다.