私はいつも!$
を使用して、前のコマンドの最後の引数を参照していました。
例えば.
~/dir » mkdir birthday
~/dir » cd !$
~/dir » cd birthday
しかし、チュートリアルで$_
の代わりに!$
が使用されているのを見始めました。
2つをテストしましたが、気付いた唯一の違いは微妙ですが、$_
はコマンドを評価して実行するのに対し、!$
はヒットする前に出力をサニティチェックできるようです。 Enter、しかしこれが$_
と!$
の唯一の違いですか?
更新:重複としてフラグが立てられましたか?この質問は、提案された質問に対して受け入れられた回答によって回答される場合がありますが、それは、回答が必要な質問よりも詳細であるためです。
_ $はどういう意味ですか?を検索すると、提案された重複が生成されますが、!$
が何をしたかを尋ねる前に、私はすでに知っていました。その質問が他の質問にも答える可能性があることを示唆するものは何もありません。質問。
man bash
、セクション特殊パラメータを検索します。 _
の場合、次のようになります。
前のコマンドの最後の引数に展開します(展開後)。
したがって、コマンドラインコンテキストでの違いは拡張です。たとえば、変数FOO
を 'bar'に設定し、echo $FOO
を実行すると、次の行で$_
が実行され、次の行でbar
が送信されます。 !$
の間にコマンドを実行すると$FOO
になります。
この動作はデフォルトでは明白ではないかもしれませんが、shopt -s histverify
を使用するともう少し明白になります。 (histverify
を有効にすると、Bashは直後に履歴拡張を送信しません Enter、最初にコマンド、拡張後を表示し、1秒待ちます Enter)。したがって、FOO=bar
の後に次のようなものが表示されます。
$ echo $FOO
bar
$ ls !$ $_
# We hit Enter and then see
$ ls $FOO $_
$_
は、パラメーターの展開中にコマンドが送信されるまで展開されません($FOO
とともに)。それは微妙な違いですが、そこに行きます。
おそらく、より興味深い/有用な区別は、$_
が変数であるということです。したがって、たとえば、最後のパラメータが/some/file/path.txt
の場合、長さ${#_} -> 19
を取得し、ファイル名のみ${_##*/} -> path.txt
を抽出し、ルート${_//some/other} -> /other/file/path.txt
を変更します。 !$
ですべてを行うことはできません。
$_
は、他のコンテキストでは異なる意味を持つことに注意してください。
シェルの起動時に、環境または引数リストで渡されたとおりに実行されているシェルまたはシェルスクリプトを呼び出すために使用される絶対パス名に設定します。
...そして...
また、実行され、そのコマンドにエクスポートされた環境に配置された各コマンドを呼び出すために使用される絶対パス名に設定します。
...そして...
メールをチェックする場合、このパラメータは現在チェックされているメールファイルの名前を保持します。
PDATE:ほぼ正確ですが、私の答えにはいくつかの重要な情報が欠けており、$_
が実際に値を取得する方法/時期について誤解を招く可能性さえあります。その最初の引用は次のように読むことを意図しています:
そのコマンドによって受信されたとき、つまりシェル拡張を実行した後、前のコマンドの最後の引数に展開されます
説明するための最良の方法は、いくつかの例を使用することです。
$ echo "$(date +%s)" # %s is seconds since Epoch
1536984661
$ echo $_ "$(date +%s)" # don't hit enter until a few seconds pass
1536984661 1536984665
したがって、$_
は、最初のecho
が実行されたときに計算された実際の秒数を取得します。2番目のdate
呼び出しの1536984665
に近いものではありません。
もう1つ:
$ foo='a b c'
$ echo "$foo"
a b c
$ echo "$_"
a b c
$ #---------
$ echo $foo
a b c
$ echo "$_"
c
2番目のケースでは、$foo
を引用しませんでした。 echo
に渡される前に、変数/パラメーターの展開とそれに続くWordの分割が行われました。引用符がないため、「a」、「b」、「c」が3つの別々のパラメータとして渡され、$_
が最後の「c」を取得しました。