방금 차이점이 정확히 무엇인지 궁금했습니다.
[[ $STRING != foo ]]
과
[ $STRING != foo ]
후자는 posix를 준수하고 sh에서 발견되고 전자는 bash에서 발견되는 확장입니다.
방금 차이점이 정확히 무엇인지 궁금했습니다.
[[ $STRING != foo ]]
과
[ $STRING != foo ]
후자는 posix를 준수하고 sh에서 발견되고 전자는 bash에서 발견되는 확장입니다.
답변:
몇 가지 차이점이 있습니다. 제 생각에는 가장 중요한 몇 가지는 다음과 같습니다.
[
Bash와 다른 많은 현대 쉘에 내장되어 있습니다. 내장 [
은 test
폐쇄의 추가 요구 사항과 유사합니다 ]
. 내장 매크로 [
및 test
기능을 모방 /bin/[
하고 /bin/test
자신의 한계와 함께 스크립트는 이전 버전과 호환 될 수 있도록. 원본 실행 파일은 여전히 대부분 POSIX 호환 및 이전 버전과의 호환성을 위해 존재합니다. type [
Bash 에서 명령 을 실행하면 [
기본적으로 기본 제공되는 것으로 해석됩니다. (참고 : which [
단지에 실행 파일을 찾습니다 PATH 와 동등하다 type -p [
)[[
호환되지는 않지만 어떤 /bin/sh
점에서도 작동하지는 않습니다 . 그래서 [[
더 현대적인 배쉬 / zsh을 / 가능한 ksh 옵션입니다.[[
쉘에 내장되어 기존의 요구 사항이 없습니다, 당신은에 따라 단어 분할에 대해 걱정할 필요가 없습니다 IFS의 공백 문자열로 평가 변수에 대한 혼란 최대 변수입니다. 따라서 변수를 큰 따옴표로 묶을 필요는 없습니다.대부분의 경우 나머지는 더 좋은 구문입니다. 더 많은 차이점을 보려면 FAQ 답변으로 연결되는 것이 좋습니다. test, [와 [[? . 실제로 bash 스크립팅에 대해 진지한 경우 FAQ, 함정 및 안내서를 포함한 전체 위키를 읽는 것이 좋습니다 . 가이드 섹션의 테스트 섹션에서는 이러한 차이점에 대해 설명 하고 이식성이 뛰어 나기 위해 걱정할 필요가없는 경우 저자 가 더 나은 선택을하는 이유를 설명합니다 . 주요 이유는 다음과 같습니다.[[
< >
입력 리디렉션으로 평가되지 않기 위해 백 슬래시 보다 작거나 크게 벗어날 필요가 없으므로 파일을 덮어 써서 실제로 물건을 엉망으로 만들 수 있습니다. 이것은 다시 [[
기본 제공 으로 돌아갑니다 . [(test)가 외부 프로그램 인 경우, 쉘은 평가하는 방식 <
과 호출되는 >
경우에만 예외를 만들어야 /bin/test
하는데 이는 실제로 의미가 없습니다.한마디로 :
[bash 내장입니다
[[]]은 강타 키워드입니다
키워드 : 키워드는 기본 제공과 매우 유사하지만 가장 큰 차이점은 특별한 구문 분석 규칙이 적용된다는 것입니다. 예를 들어, [는 bash 내장이고, [[는 bash 키워드입니다.) 그것들은 둘 다 물건을 테스트하는 데 사용되지만 [[는 내장이 아닌 키워드이므로 몇 가지 특별한 구문 분석 규칙의 이점을 통해 훨씬 쉽게 만들 수 있습니다.
$ [ a < b ]
-bash: b: No such file or directory
$ [[ a < b ]]
bash는 파일 b를 명령 [a]로 경로 재 지정하려고하기 때문에 첫 번째 예제는 오류를 리턴합니다. 두 번째 예는 실제로 예상대로 수행합니다. <문자는 더 이상 File Redirection 연산자의 특별한 의미가 없습니다.
출처 : http://mywiki.wooledge.org/BashGuide/CommandsAndArguments
[
POSIX 쉘 명령입니다. 내장되어있을 필요는 없습니다. ]
구문이 균형을 이루도록 명령이 찾는 인수 일뿐입니다. 이 명령은 닫기를 찾지 않는 test
것을 제외하고 동의어입니다 . test
]
행동 차이
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 동등한 ², 다음을 참조하십시오 : https://stackoverflow.com/questions/21294867/how-to-test-strings-for-lexicographic-less-than-or-equal-in-bash/52707989#52707989&&
과 ||
[[ 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?
글로브가 확장됩니다. 따라서 현재 디렉토리의 파일에 따라 true 또는 false 일 수 있습니다.[ ab = a\? ]
: false, glob 확장이 아님=
와 ==
모두 동일 [
하고 [[
있지만, ==
배쉬 확장입니다.case ab in (a?) echo match; esac
: POSIX 상당[[ ab =~ 'ab?' ]]
: 거짓 4 , 마법을 잃는다''
[[ 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"
둘 다 해결합니다.
³도의 일부 값 실패 a
나 b
같은 !
나 (
.
4 떠들썩한 파티 3.2 이상 및 3.1 날리고 제공 호환성 (와 같이 사용할 수 없습니다 BASH_COMPAT=3.1
)
5 및 쉘 연산자 ( 및 연산자 또는 / 연산자 와 반대 )가 동일한 우선 순위를 갖기 때문에 그룹화 (여기서 {...;}
명령 그룹을 사용 (...)
하여 불필요한 서브 쉘을 실행 함)는 필요하지 않습니다 . 따라서 동일합니다.||
&&
||
&&
[[...]]
-o
-a
[
[ a = a ] || [ a = b ] && [ a = b ]
printf 'ab' | grep -Eq 'ab?'
내 에서 사용하는 방법 if [ … ]
?
if ( printf 'ab' | grep -Eq 'a' ); then echo 'a'; fi
. []
같은 명령 grep
입니다. 은 ()
해당 명령에 필요하지 않을 수도 잘 모르겠어요 : 나는 때문에의를 추가 |
, 배쉬 일을 구문 분석 방법에 따라 달라집니다. 없다면 |
나는 당신이 그냥 쓸 수 있다고 확신합니다 if cmd arg arg; then
.
()
: stackoverflow.com/questions/8965509/…
단일 브래킷 즉 []
, 조건식을 묶는 데 POSIX 셸을 준수합니다.
이중 브래킷 ( 즉 [[]]
, 표준 POSIX 버전의 확장 (또는 확장) 버전)은 bash 및 기타 쉘 (zsh, ksh)에서 지원됩니다.
배쉬에서, 우리가 사용하는 숫자 비교를 위해 eq
, ne
, lt
그리고 gt
비교를 위해 두 배 브래킷, 우리가 사용할 수있는 ==
, !=
, <,
및 >
문자 그대로.
[
테스트 명령의 동의어입니다. 쉘에 내장되어 있어도 새로운 프로세스를 생성합니다.[[
프로그램이 아닌 키워드 인 새로운 개선 된 버전입니다. 예를 들면 다음과 같습니다.
[ var1 lt var2] #works
[ var1 < var2] #error: var2 No such file or directory
[ var1 \< var2] #works with escape
[[ var1 < var2]] #works
if
문장 의 맥락에서 대괄호를 사용하지 않는 것에 대해 궁금한 경우 mywiki.wooledge.org/BashPitfalls#if_.5Bgrep_foo_myfile.5D