$ _ vs!$。前のコマンドと出力リダイレクトの最後の引数


28

問題は特殊変数に関するものです。ドキュメントは言う:

!!:$

前のコマンドの最後の引数を指定します。これは!$に短縮できます。


$_、アンダースコア。)シェルの起動時に、環境または引数リストに渡されて実行されるシェルまたはシェルスクリプトを呼び出すために使用される絶対パス名に設定します。その後、展開後、前のコマンドの最後の引数に展開します。また、そのコマンドにエクスポートされた環境で実行および配置された各コマンドの呼び出しに使用されるフルパス名に設定されます。

次の理由により、キャッチできない違いがあるはずです。

$ echo "hello" > /tmp/a.txt
$ echo "!$"
echo "/tmp/a.txt"
/tmp/a.txt

$ echo "hello" > /tmp/a.txt
$ echo $_
hello

違いはなんですか?


4
!$は履歴拡張であり、特別な変数ではないため、bashコードはそれらを異なる方法で処理すると想定します。
ジェフシャラー

2
Bourneシェル言語はおそらく、のいずれか①:私はこの質問に対する明確な答えを持っていますが、いない、まだ今日広く使用され、少なくとも内部的に一貫性のあるプログラミング言語。一般原則を推測しようとしても、何も得られません。特別なルールをすべて覚えておくだけです。ごめんなさい。②の定義で、強調表示したフレーズの直後の「展開後」という言葉に注意してください。それは重要です。それはあなたを困惑させる違いを説明しないかもしれませんが、それは他の多くの方法を説明し、同じではありません。$_$_!$
-zwol

回答:


32

!$それはの前のコマンドの最後の言葉に展開、履歴展開の単語指示である歴史。IOW、履歴の前のエントリの最後の単語。通常、この単語はコマンドの最後の引数ですが、リダイレクトの場合はそうではありません。に:

echo "hello" > /tmp/a.txt

コマンド全体'echo "hello" > /tmp/a.txt'が歴史に登場し/tmp/a.txt、そのコマンドの最後の言葉です。

_はシェルパラメータであり、前のコマンドの最後の引数に展開されます。ここで、リダイレクトはコマンドに渡される引数の一部ではないためhello、引数はにのみ渡されechoます。それがに$_拡張されhelloた理由です。

_シェル標準の特殊パラメーターの 1つではなくなりました。それはで動作しbashzshmkshおよびdash、場合にのみ、対話型のksh932つのコマンドが分離ライン上にあるときにのみ:

$ echo 1 && echo $_
1
/usr/bin/ksh

$ echo 1
1
$ echo $_
1

1
!$展開対$_パラメーターの効果の1つecho $_は、ヒストリーに常にとして表示されるのecho $_に対しecho !$、それが展開された値を表示することです。例えばecho one two、その後echo !$、上に押してショーecho two
ジャックトース
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.