그래서 저는 GIT를 처음 접했고 따라서 bash 명령과 스크립트를 처음 접했기 때문에 다양한 구문과 스크립트에 대한 도움을 찾고 있었습니다. 이제 나는 많은 도움을 얻었고 Git 경험을 훨씬 더 즐겁게 만들어줄 스크립트와 별칭을 만들 수 있게 되었습니다.
그러나 특히 "if" 명령과 관련된 미묘한 차이를 발견했습니다.
if [ -z $1 ] ; #<- Zero length string
if [[ -z $1 ]] ; #<- Also Zero Length String
if [[ "$1" == -* ]] ; #<- Starts with - (hyphen)
if [ -z $1 ] && [ -z $2 ] ; #<- both param 1 & 2 are zero length
if [[ -z $1 ]] && [[ -z $2 ]] ; #<- Also both param 1 & 2 are zero length
if [[ "$1" == -* ]] || [[ "$2" == -* ]] ; #<- Either param 1 or 2 starts with -
if [ "$1" == -* ] || [ "$2" == -* ] ; #<- Syntax Failure, "bash: ]: too many arguments"
왜 차이가 있나요? [[(이중 정밀도)가 필요한 시기와 [(단정밀도)가 필요한 시기를 어떻게 알 수 있나요?
Jaeden "Sifo Dyas" al'Raec Ruiner에게 감사드립니다.
답변1
먼저, 두 유형의 괄호 모두 구문의 일부가 아니라는 점에 유의하세요
if
. 대신에:
[
내장 쉘의 또 다른 이름입니다test
.[[ ... ]]
구문과 의미가 다른 별도의 내장 함수입니다.
다음은 bash 문서에서 발췌한 내용입니다.
[
/test
test: test [expr]
Evaluate conditional expression.
Exits with a status of 0 (true) or 1 (false) depending on
the evaluation of EXPR. Expressions may be unary or binary. Unary
expressions are often used to examine the status of a file. There
are string operators and numeric comparison operators as well.
The behavior of test depends on the number of arguments. Read the
bash manual page for the complete specification.
File operators:
-a FILE True if file exists.
(...)
[[ ... ]]
[[ ... ]]: [[ expression ]]
Execute conditional command.
Returns a status of 0 or 1 depending on the evaluation of the conditional
expression EXPRESSION. Expressions are composed of the same primaries used
by the `test' builtin, and may be combined using the following operators:
( EXPRESSION ) Returns the value of EXPRESSION
! EXPRESSION True if EXPRESSION is false; else false
EXPR1 && EXPR2 True if both EXPR1 and EXPR2 are true; else false
EXPR1 || EXPR2 True if either EXPR1 or EXPR2 is true; else false
When the `==' and `!=' operators are used, the string to the right of
the operator is used as a pattern and pattern matching is performed.
When the `=~' operator is used, the string to the right of the operator
is matched as a regular expression.
The && and || operators do not evaluate EXPR2 if EXPR1 is sufficient to
determine the expression's value.
Exit Status:
0 or 1 depending on value of EXPRESSION.
더 간단히 말하면 [
bash 표현식은 정상적으로 처리되어야 하며 보간 등을 피하기 위해 인용되어야 합니다. 따라서 $foo
빈 문자열인지 설정되지 않았는지 테스트하는 올바른 방법은 다음과 같습니다.
[ -z "$foo" ]
또는
[[ -z $foo ]]
첫 번째 경우에는 참조가 중요합니다. 왜냐하면 foo="a b"
다음 테스트를 설정하면 두 개의 매개변수가 수신 [ -z $foo ]
되는 결과가 test -z
올바르지 않기 때문입니다.
언어는 [[ .. ]]
다르며 bash보다 더 높은 수준의 언어에서 기대할 수 있는 방식으로 변수를 올바르게 이해합니다. 따라서 [
classic/ 보다 오류가 발생할 가능성이 적습니다 test
.
답변2
man bash
문서를 입력 하고 읽어 보십시오.
거기에서 찾을 수 있는 것:
if list; then list; [ elif list; then list; ] ... [ else list; ] fi
The if list is executed. If its exit status is zero, the
then list is executed. Otherwise, each elif list is executed
in turn, and if its exit status is zero, the corresponding
then list is executed and the command completes. Otherwise,
the else list is executed, if present. The exit status is
the exit status of the last command executed, or zero if no
condition tested true.
즉, if
그 뒤에는 어떤 명령이라도 있을 수 있으며 bash는 해당 명령의 반환 값에만 관심을 갖습니다. 위에서 [
는 및 의 두 가지 다른 명령을 사용했습니다 [[
.
test expr
[ expr ]
Return a status of 0 (true) or 1 (false) depending on the
evaluation of the conditional expression expr. Each operator
and operand must be a separate argument. Expressions are
composed of the primaries described above under CONDITIONAL
EXPRESSIONS. test does not accept any options, nor does it
accept and ignore an argument of -- as signifying the end of
options. [...]
이것은 많은 쉘에서 사용할 수 있는 고전적인 테스트입니다.
[[ expression ]]
Return a status of 0 or 1 depending on the evaluation of the
conditional expression expression. Expressions are composed
of the primaries described below under CONDITIONAL EXPRES‐
SIONS. Word splitting and pathname expansion are not per‐
formed on the words between the [[ and ]]; tilde expansion,
parameter and variable expansion, arithmetic expansion, com‐
mand substitution, process substitution, and quote removal
are performed. Conditional operators such as -f must be
unquoted to be recognized as primaries.
When used with [[, the < and > operators sort lexicographi‐
cally using the current locale.
When the == and != operators are used, the string to the
right of the operator is considered a pattern and matched
according to the rules described below under Pattern Match‐
ing, as if the extglob shell option were enabled. The =
operator is equivalent to ==. If the shell option nocase‐
match is enabled, the match is performed without regard to
the case of alphabetic characters. The return value is 0 if
the string matches (==) or does not match (!=) the pattern,
and 1 otherwise. Any part of the pattern may be quoted to
force the quoted portion to be matched as a string.
이것은 약간 다른 의미를 지닌 bash의 확장입니다. 특히 ==
정의가 다릅니다. 첫 번째는 문자 그대로의 비교를 수행하고 두 번째는 용량 와일드카드 일치를 수행합니다.
답변3
의심스러운 경우(bash에서),언제나이중 중괄호( [[ ]]
)는 단일 중괄호의 상위 집합이고 호출 시 사용자 오류가 발생하기 쉽기 때문에 사용합니다.
[
bash의 내부 명령이지만 다른 환경에서는 /bin/test
심볼릭 링크 가 될 수 있습니다. 해당하는 것들은 ]
실제로 무시되고 아름다움을 위해 존재합니다. 궁극적으로 if /bin/test -z "$VAR"
및 는 동일한 설명입니다(단, 환경에 따라 하위 프로세스가 이름으로 호출될 수도 있고 호출되지 않을 수도 있음).if [ -z "$VAR" ]
[
/bin/test
[[ ]]
또한 bash의 내부주의이므로 하위 쉘이 없으며 이는 상위 집합 [ ]
이며 더 친숙한 작성을 허용하므로 "올바른 일을 수행"하고 [ ]
폭발할 것입니다.
http://mywiki.wooledge.org/BashFAQ/031입력하다많은자세한 내용은.