インタラクティブシェルの感嘆符(!)
1. 概要
インタラクティブなLinuxコマンドラインで多くの作業を行う場合、感嘆符に出くわした可能性があります。 ほとんどのシェルでは、このシンボルは、履歴の拡張を通じて以前に実行されたコマンドを再実行するために使用され、それによって生産性が向上します。
このチュートリアルでは、「!」のいくつかの使用例について説明します。 シェル履歴からコマンドを再実行するための記号。
2. シェル履歴の拡張
bash 、 csh 、 zsh などの最も一般的なシェルは、以前にシェルで実行したコマンドの履歴を保存できます。 これらのコマンドは、通常はホームディレクトリにある履歴ファイルに1行ずつ保存されます。
「!
この機能は、デフォルトで、一般的なシェルですでに有効になっています。 ただし、気に入らない場合は、 set +Hを使用して無効にすることができます。
「!」の魔法を見てみましょう動作中のシンボル。
2.1. 最後のコマンドを繰り返す(!!)
通常、
$ echo "Hello, World"
Hello, World
$ !!
echo "Hello, World"
Hello, World
たとえば、プログラムの複数のインスタンスを強制終了する場合は、 pkill コマンドを1回入力してから、「!!」で繰り返します。
$ pkill node
$ !!
pkill node
2.2. 番号によるコマンドの繰り返し(!n)
ご存知のように、シェルはプレーンテキストファイルで行ごとに履歴を追跡します。 履歴ファイルの行番号を「!」の引数として指定することで、特定のコマンドを再実行できます。
bash 履歴ファイルから最も古い(最初の)5つのコマンドを出力してみましょう。
$ cat ~/.bash_history -b | head -n5
1 nvpk
2 sudo pacman -Ss pipewire
3 sudo pacman -Ss xdg-desktop
4 install wofi wofi-calc wofi-emoji-git
5 shutdown -h 60
catの-bオプションは、行の前に行番号を追加します。 この情報を使用して、履歴ファイルの5番目のコマンドを繰り返すことができます。
$ !5
shutdown -h 60
Shutdown scheduled for Sun 2022-05-10 02:07:31 PKT, use 'shutdown -c' to cancel.
シェル履歴をクリアしない限り、各コマンドの行番号は変更されません。したがって、ファイル内の行番号を記憶することで、長いコマンドを繰り返すことができます(時間がかかりますが、時間を節約できます) )。
同様に、「!」に負の数を指定することもできます。 履歴ファイルのn番目の前のコマンドを再実行するには:
$ cat ~/.bash_history -b | tail -n5
96 nvim ./set-bg
97 nvim ../../.config/sway/config
98 ./set-bg
99 grep Verbose /etc/pacman.conf
100 sudo pacman -Ss wofi
$ !-2
grep Verbose /etc/pacman.conf
#VerbosePkgLists
2.3. パターンを使用してコマンドを繰り返す(!pattern)
履歴ファイルで前のコマンドの行番号を検索する手間は、時間がかかる場合があります。 幸い、「!」と入力できますシンボルの後にパターンが続き、そのパターンに一致する前のコマンドを実行します。
たとえば、greppingを含む最後のコマンドを実行してみましょう。
$ !grep
grep Verbose /etc/pacman.conf
#VerbosePkgLists
ただし、開始パターンのみが想定されていることを知っておく必要があります。以下は機能しません。
$ !pacman.conf
bash: !pacman.conf: event not found
2.4. 前のコマンドでのファイルパスの再利用(!$)
コマンド全体を繰り返す必要がなく、前のコマンドの一部だけが必要な場合もあります。 幸いなことに、「!」 その点についてもカバーしてくれました。
たとえば、前のコマンドで指定したファイルパスを再利用する場合は、「!$」を使用できます。
$ cat ~/.bash_history
1 nvpk
2 sudo pacman -Ss pipewire
3 sudo pacman -Ss xdg-desktop
4 install wofi wofi-calc wofi-emoji-git
5 shutdown -h 60
.
.
.
$ file $?
file ~/.bash_history
/home/hey/.bash_history: ASCII text
2.5. 前のコマンドの引数の再利用(!*)
前のコマンドの引数を再利用することもできます。 一連のテキストファイルを作成する例を考えてみましょう。
$ touch index.html index.css index.js
ここで、 index.js ファイルを削除する場合は、その引数を「!:3」で参照できます。
$ rm !:3
同様に、「!:nm」表記で引数の範囲を指定できます:
$ touch style.js head.css foot.css side.css
$ mv !:1-3 style/
このコマンドは、 head.css 、 foot.css 、および side .cssファイルを
さらに、前のコマンドのすべての引数を「!*」で使用することもできます。
2.6. sudo コマンド( sudo !!)
「!」の前にsudoと入力することで、root権限を必要とする前のコマンドを実行することもできます。 シンボル:
$ mount /dev/sda3 /mnt
mount: /mnt: must be superuser to use mount.
$ sudo !!
3. 代替案:シェル履歴を検索する
昔は、インタラクティブシェルにショートカットは実装されていませんでした。 つまり、「!」 symbolは、Linuxユーザーが前のコマンドを繰り返すための頼りになるツールでした。
時間の経過とともに、シェルは非常に高度になり、インタラクティブなコマンドラインを使用するための多くの生産的な方法が導入されました。 機能の1つには、シェル履歴の検索が含まれます。
$ grep Verbose /etc/pacman.conf
bck-i-search: gre|
入力すると
特定のパターンに対して複数の結果がある場合は、を押すことができます
したがって、要するに、最後のコマンドを繰り返すために履歴拡張機能を使用する代わりに、このアプローチを使用する方が良いです。 ただし、前のコマンドの一部が必要な場合は、いつでも履歴展開を使用できます。
4. 結論
このチュートリアルでは、インタラクティブシェルの履歴拡張機能について説明し、そのいくつかのユースケースを確認しました。 最後に、シェル履歴をすばやく検索する履歴拡張機能を使用する代わりの方法について説明しました。