StackOverflow answer 3.5Kを超える投票では、現在のbashスクリプトのディレクトリをDIR
に割り当てるためのこの1行が特徴です。
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
ネストされた二重引用符に戸惑っています。私の知る限り、次のフラグメントは二重引用符で囲まれています。
"$( cd "
"${BASH_SOURCE[0]}"
" && pwd )"
...および=
の右側にあるその他すべて(つまり、$( dirname
および)
)は引用符で囲まれていません。つまり、2番目、4番目、6番目の"
文字は、それぞれ1番目、3番目、5番目の"
文字を「閉じる」と想定しています。
"${BASH_SOURCE[0]}"
の二重引用符が何を実現するか理解しましたが、他の2組の二重引用符の目的は何ですか?
一方、上記のスニペットが正しくない(そして高い投票スコアにかかわらず)場合、その名目的を達成するための正しい方法は何ですか?
((公称意図によって):つまり、最初にpwd
- ingを実行した後、cd
によって返された値を、返されたディレクトリに収集しますdirname "${BASH_SOURCE[0]}"
によって、サブシェルでcd
- ingを実行して、親シェルの$PWD
が変更されないようにします)。
あなたのパズルは、bash
(および一般的にシェル)が入力をどのように解析したかについて正しくありません。に:
_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
_
最初に、bash
は、1つの長い文字列$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
への代入の右側を解析します。二重引用符は、 double quotes の内部に表示できるためです。
その後、bash
はコマンド置換の解析を開始します。開き括弧から囲み括弧までのすべての文字は、コマンド置換内のコマンドの作成に使用されるため、次のようになります。
_cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd
_
シェルは引き続きその複合コマンドの解析を行い、2つの部分に分割します。
cd "$( dirname "${BASH_SOURCE[0]}" )"
次に、同じ解析ルールをcd "$( dirname "${BASH_SOURCE[0]}" )"
に適用しますが、今回は二重引用符は冗長ではありませんが、意味があります。これらは、$( dirname "${BASH_SOURCE[0]}" )
の結果のフィールド分割、および_${BASH_SOURCE[0]}
_の展開を防ぎます(最も外側の二重引用符とは対照的に、 はRHSでは必要ありません) _split+glob
_ )を防ぐための変数割り当ての例。
このルールは、すべてのPOSIXシェルの コマンド置換 に適用されます。より詳細なパズルは、POSIX仕様の Token Recognitionセクションで読むことができます 。
$(...)
の中に入ると、引用は最初からやり直しになります。
言い換えると、_"..."
_と$(...)
は、相互にnestできます。プロセス置換$(...)
には、1つ以上のcomplete二重引用符付き文字列を含めることができます。また、二重引用符で囲まれた文字列には、1つ以上のcompleteプロセス置換が含まれる場合があります。 しかし、それらはインターレースしません。したがって、プロセス置換の内部で始まる二重引用符で囲まれた文字列は、外部に拡張されることはありません。
だから、考慮してください:
_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
_
内部の$(...)
の内部は次のとおりです。
_dirname "${BASH_SOURCE[0]}"
_
上記の_${BASH_SOURCE[0]}
_は二重引用符で囲まれています。 _${BASH_SOURCE[0]}
_が二重引用符で囲まれていると判断する場合、$(...)
の外側にある二重引用符または単一引用符は関係ありません。
外側の$(...)
には以下が含まれます:
_cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd
_
ここでは、式$( dirname "${BASH_SOURCE[0]}" )
が二重引用符で囲まれています。外側の$(...)
の外側に引用符があるという事実は、その内側に何があるかを考えると無関係です。内部の$(...)
内に引用符があることも関係ありません。