だから私は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"
、次のテストを設定すると、2つのパラメータを受け取った[ -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はそのコマンドの戻り値にのみ興味があります。上記では[
、との2つの異なるコマンドを使用しました[[
。
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の拡張です。特に==
定義が異なります。 1つ目は文字通りの比較を行い、2つ目は容量ワイルドカードマッチングを行います。
答え3
疑わしい場合(bashで)、いつも二重中括弧([[ ]]
)は単一の中括弧の親セットであり、呼び出し時にユーザーエラーが発生しやすいために使用します。
[
bashの内部コマンドですが、他の環境では/bin/test
シンボリックリンクになることがあります。対応するものは]
実際に無視され、美しさのために存在します。最終的にはif /bin/test -z "$VAR"
、とは同じ説明です(ただし、環境によっては子プロセスが名前で呼び出されることも、呼び出されない場合もあります)。if [ -z "$VAR" ]
[
/bin/test
[[ ]]
また、bashの内部主義なので、サブシェルはなく、これは親セットであり、より使い慣れ[ ]
た作成を可能にするので、「正しいことを行う」と[ ]
爆発します。
http://mywiki.wooledge.org/BashFAQ/031入力するたくさん詳細については。