歴史的拡張はいつ起こるか。
バッシュマニュアルから
文字を二重引用符( ''')で囲むと、履歴拡張が有効になっている場合は、 '$'、 '''、 '\'、および '!'以外の引用符内のすべての文字のリテラル値が保持されます。
パーサーは解析段階で二重引用符を認識するので、解析後に履歴拡張を実行する必要がありますか?
それでは、シェル拡張(中括弧拡張、パラメータ拡張、ファイル名拡張など)はいつ発生しますか?
しかし、履歴拡張はシェルのreadlineによって提供されるので、語彙分析と構文解析の前に処理されると思いました。シェルのオートコンプリートと同じです。私は何を逃したことがありませんか?
ありがとうございます。
答え1
引用するバッシュマニュアル:
履歴拡張は、シェルが行を単語に分割する前に行全体を読み取った直後に行われます。
履歴拡張は、シェルの構文解析の前でも処理の最初のステップであるため、二重引用符が使用されます。いいえprotected !
:後者は二重引用符の前に処理されます。これは、独自の構文解析を実装し、履歴演算子を保護するさまざまな方法を持つ履歴ライブラリによって処理されます。
歴史的拡張文字をエスケープするために ' ' と
\
''
' のみを使用できますが、歴史的拡張文字も二重引用符で囲まれた文字列で閉じる二重引用符の直前にある場合は引用符で扱われます。
シェルのパーサが文字列処理を開始すると、すでに履歴ライブラリによって解析され、履歴拡張が発生しました。
答え2
@Stephen Kittが言ったように、記録の拡張は最初のステップで行われるべきです。このパターンは次のように理解できます。任意のbashコードを入力すると、次のようになります。
echo "the value of a is $a" > tmp
次に、使用履歴拡張を使用します。
!-1
明らかに、上記の行は同じことをやり直します。私たちが注目すべき点は、最初!-1
に拡張されることです。この拡張が解析ステップの後に発生した場合、正しく解析されませんが、実際には発生しないことにecho "the value of a is $a" > tmp
気づく必要があります。$a