こんにちは!
InfraAcademyを運営しております、藤田と申します!
今回の記事では、Linuxのビックリマーク(!)について解説します!
結論から言うと、Linuxのビックリマーク(!)は、過去に実行したコマンドを呼び出して再実行するための記号です。bashの履歴展開(ヒストリ展開)と呼ばれる機能で、使いこなせるとターミナルでの作業効率が大きく変わります。
Linuxのコマンド操作に慣れてくると、効率的にコマンドを使いこなす方法を学びたくなりますよね。そんなときに知っておきたいのが、ビックリマーク(!)を使ったコマンド操作です。
この記事では、!!や!番号といった基本の使い方から、sudo !!や!$などの時短テクニック、event not foundエラーの対処法まで、順番に紹介していきます。
Linuxのビックリマーク(!)とは?履歴展開という機能¶
まずは、ビックリマークがどんな役割を持つ記号なのかを整理していきましょう。
Linuxのターミナルでは、!(エクスクラメーションマーク)を使うことで、以前実行したコマンドを呼び出したり、特定のコマンドを繰り返し実行することができます。
この機能は、bashでは履歴展開(History Expansion)と呼ばれています。シェルが記録しているコマンド履歴を、!という合図で呼び出しているわけです。
特に、過去に入力したコマンドの履歴を参照し、すばやくコマンドを再実行する場合に便利です。例えば、長いコマンドをもう一度打つのは面倒ですよね。
そこで、ビックリマークを使えば短い文字列で過去のコマンドを再利用できます。↑キーを何十回も押して履歴をさかのぼる必要もなくなり、作業効率が大幅にアップします!
履歴展開が動く仕組み¶
そもそも、なぜ!で過去のコマンドを呼び出せるのでしょうか。仕組みを知っておくと、エラーが起きたときにも落ち着いて対処できます。
bashは、あなたが実行したコマンドを1件ずつ履歴として記録しています。この履歴は、シェルを終了するときにホームディレクトリの.bash_historyというファイルへ保存されます。
!を含むコマンドラインを入力すると、bashは実行の前に履歴から該当するコマンドを探し出し、入力内容を置き換えます。この置き換えの処理こそが、履歴展開の正体です。
つまり、!!や!lsは独立したコマンドではなく、シェルの展開機能なんですね。この点を押さえておくと、後半で紹介するエラーの原因もすっと理解できます。
ビックリマーク(!)の基本的な使い方¶
それでは、実際の使い方を見ていきましょう。まずは、使う頻度がもっとも高い基本のパターンからです。
!!で直前に実行したコマンドをそのまま再実行¶
!!(ビックリマーク2つ)は、直前に実行したコマンドをそのまま再実行するコマンドです。
以下のように実行します。
sudo apt update
!!
上記の例では、2行目の!!がsudo apt updateのコマンドを呼び出し、再度実行します。
そして、!!が真価を発揮するのがsudo !!という組み合わせです。間違ってapt updateを権限不足で実行してしまった場合でも、sudo !!と入力すれば、直前のコマンドを管理者権限付きで実行し直せます。
Permission deniedと表示されて、長いコマンドを最初から打ち直した経験はありませんか。sudo !!を覚えておけば、そのストレスから解放されます。
なお、そもそもなぜ権限エラーが起きるのかを復習したい方は、Linuxのファイル権限の解説記事もあわせてご覧ください。
![コマンド]で特定のコマンドを再実行する¶
![コマンド]の形式を使えば、指定した文字列で始まるコマンドを履歴から検索し、最後に実行したそのコマンドを再実行できます。
例えば、以下のように実行します。
ls -l /var/log
cd /home/user
!ls
上記の例では、3行目の!lsがls -l /var/logを再実行します。直前ではなく、少し前に実行した特定のコマンドを探して再実行したいときに便利です。
注意したいのは、!lsが前方一致で検索されるという点です。もし履歴の新しい側にlsblkのような別のコマンドがあれば、そちらがマッチしてしまいます。
文字列の一部だけで探したい場合は、!?log?のように!?文字列?の形式を使います。こちらはコマンドライン全体から、部分一致で検索してくれます。
![番号]で番号を指定してコマンドを実行する¶
過去のコマンド履歴を、番号指定で実行することも可能です。コマンド履歴はhistoryコマンドを使って確認できます。
history
1 ls -l
2 cd /var
3 echo "Hello World"
4 sudo apt update
!3
→Hello World
この場合、!3と入力するとecho "Hello World"が実行されます。特定の履歴番号を呼び出したいときに有効です。
履歴が何百件もあるときは、history | grep aptのように絞り込むと、目的の番号をすぐに見つけられます。grepの使い方に自信がない方は、grepコマンドで文字を検索する方法で詳しく解説しています。
また、!-3のようにマイナスを付けると、3個前に実行したコマンドという相対指定もできます。!-1は!!とまったく同じ意味です。
ここまでに登場した指定方法を、表で整理しておきましょう。
| 書き方 | 意味 |
|---|---|
!! |
直前のコマンドを再実行 |
!n |
履歴番号nのコマンドを再実行 |
!-n |
n個前のコマンドを再実行 |
!文字列 |
その文字列で始まる直近のコマンドを再実行 |
!?文字列? |
その文字列を含む直近のコマンドを再実行 |
すべてを一度に覚える必要はありません。まずは!!と!文字列の2つが手になじめば十分です。
!$や^old^new^で効率化する応用テクニック¶
基本を押さえたら、次は一歩進んだテクニックです。ビックリマークは、コマンド全体だけでなく引数だけを取り出すこともできます。
実は、現場のエンジニアがいちばんよく使うのはこちらの使い方かもしれません。中でも!$は定番中の定番です。
!$で直前コマンドの最後の引数を使い回す¶
!$は、直前に実行したコマンドの最後の引数に展開されます。
例えば、mkdir /var/www/myappでディレクトリを作った直後にcd !$と打てば、cd /var/www/myappとして実行されます。長いパスを2回打つ必要がなくなるわけです。
ファイルの中身をcat /etc/nginx/nginx.confで確認した後に、viで開き直したい場面でも活躍します。vi !$と打つだけで、同じファイルをそのまま開けます。
viでの編集そのものを速くしたい方は、viで効率良くファイルを編集するコマンド5選も参考にしてみてください。
!^や!*でほかの引数も取り出せる¶
最後の引数以外も、同じように取り出せます。指定方法を表にまとめました。
| 書き方 | 展開される内容 |
|---|---|
!$ |
直前コマンドの最後の引数 |
!^ |
直前コマンドの最初の引数 |
!* |
直前コマンドの引数すべて |
!!:2 |
直前コマンドの2番目の引数 |
例えば、cp file1.txt file2.txt /tmpの後にls !*と打つと、ls file1.txt file2.txt /tmpとして実行されます。
こちらも丸暗記は不要です。まずは!$だけ体で覚えて、必要になったらこの表に戻ってくるくらいの気持ちで大丈夫ですよ。
^old^new^で打ち間違いを修正して再実行¶
コマンドの一部だけを打ち間違えたときは、置換のテクニックが便利です。
^old^new^という書き方をすると、直前のコマンドのoldの部分をnewに置き換えて再実行できます。例えばsudo apt updeteとタイプミスした直後に^updete^update^と打てば、正しいsudo apt updateが実行されます。
同じことは!!:s/updete/update/という書き方でも可能です。まずは、シンプルな^old^new^のほうから覚えるのがおすすめです。
:pで実行せずに展開結果だけ確認する¶
便利な履歴展開ですが、少し怖い側面もあります。!番号の番号を取り違えると、意図しないコマンドがいきなり実行されてしまうからです。
もしrmのような削除系コマンドを誤って呼び出したら、と考えるとヒヤッとしますよね。そこで覚えておきたいのが、末尾に付ける:pという修飾子です。
!3:pのように打つと、コマンドは実行されず、展開された内容が画面に表示されるだけになります。表示されたコマンドは履歴の最新として追加されるため、内容を確認した上で!!を打てばそのまま実行できます。
削除や上書きをともなうコマンドを履歴から呼び出すときは、まず:pで展開結果を確認してから実行する。この習慣をつけておくと、うっかり事故をぐっと減らせます。
event not foundエラーが出るときの対処法¶
ここからは、ビックリマークにまつわる代表的なトラブルを取り上げます。echoで感嘆符入りの文字列を出力しようとして、エラーになった経験はありませんか。
例えば、次のようなケースです。
$ echo "Hello World!"
bash: !": event not found
event not foundは、直訳すると該当するイベントが見つからないという意味です。bashが!"を履歴展開の指定だと解釈し、マッチする履歴が存在しなかったためにエラーになっています。
ポイントは、ダブルクォートの中でも履歴展開が発動してしまうという点です。ここが、初心者の方がもっともつまずきやすい落とし穴と言えます。
対処法の1つ目は、シングルクォートで囲むことです。echo 'Hello World!'のように書けば履歴展開は完全に無効になるため、いちばん簡単で確実な方法です。
2つ目は、\!のようにバックスラッシュでエスケープする方法です。ただし、ダブルクォートの中ではバックスラッシュが文字として残ってしまうため、基本はシングルクォートを使うほうが無難です。
3つ目は、set +Hで履歴展開そのものを無効化する方法です。そのシェルでは!が普通の文字として扱われるようになり、元に戻したいときはset -Hを実行します。
ちなみに、シェルスクリプトの中では履歴展開は最初から無効になっています。このエラーが起きるのは、ターミナルで対話的に操作しているときだけです。
↑キーやCtrl+Rとの使い分け¶
過去のコマンドを呼び出す方法は、ビックリマークだけではありません。↑キーやCtrl+Rも、同じ目的でよく使われる機能です。
それぞれに得意な場面があるので、違いを整理しておきましょう。
| 方法 | 操作イメージ | 得意な場面 |
|---|---|---|
| ↑キー | 履歴を1つずつさかのぼる | 数回前までの直近のコマンド |
| Ctrl+R | キーワードで履歴を逐次検索 | 内容をうろ覚えの古いコマンド |
!系 |
記号で指定して即再実行 | 対象が明確なときの最速の再実行 |
history+!番号 |
一覧から番号で選ぶ | 履歴全体を見渡して選びたいとき |
Ctrl+Rを押すと、画面が(reverse-i-search)という表示に切り替わります。ここで文字を打つと、履歴がリアルタイムに検索されていく仕組みです。
Ctrl+Rは、実行前に候補を目で確認できるため安全性の面で優れています。一方の!系は、確認を挟まないぶんタイプ数が少なく、スピードでは上回ります。
どちらか一方に絞る必要はありません。直前のコマンドなら!!、うろ覚えの古いコマンドならCtrl+R、というように自分なりの型を作っていきましょう。
ビックリマークのその他の意味も知っておこう¶
ここまで解説してきたのは、履歴展開としての!でした。しかしLinuxの世界では、ビックリマークが別の意味で使われる場面もあります。
検索でこの記事にたどり着いた方の中には、こちらの意味を探していた方もいるのではないでしょうか。代表的なものを表にまとめました。
| 書き方 | 意味 |
|---|---|
#!/bin/bash |
シバン。スクリプトを実行するプログラムの指定 |
if ! コマンド |
否定。コマンドの成否を反転させる |
find ! -name "*.txt" |
条件の否定。txt以外のファイルを探す |
$! |
直前にバックグラウンド実行したプロセスのID |
!= |
比較演算子。等しくないことを表す |
シェルスクリプトの1行目にある#!は、シバン(shebang)と呼ばれる特別な記述です。履歴展開とはまったくの別物で、そのスクリプトをどのプログラムで実行するかを指定しています。
if文やfindコマンドで使う!は、条件を反転させる否定の意味です。プログラミング言語のNOT演算子と同じ感覚ですね。
同じ記号でも、置かれる場所によって意味が変わるのがシェルの奥深いところです。同じく記号でつまずきやすい>や>>については、リダイレクト演算子の解説記事で詳しく紹介しています。
ビックリマークに関するよくある疑問¶
最後に、ビックリマークについて初心者の方からよく聞かれる疑問に答えておきます。
zshやmacOSのターミナルでも使える?¶
最近のmacOSでは、標準シェルがbashではなくzshになっています。zshでもビックリマークは使えるのか、気になりますよね。
結論としては、zshでも!!や!番号などの履歴展開はほぼ同じ感覚で使えます。macOSのターミナルでも、この記事の内容はそのまま試せますよ。
コマンド履歴はどこに保存されている?¶
bashのコマンド履歴は、ホームディレクトリの.bash_historyというファイルに保存されています。cat ~/.bash_historyとすれば、中身を直接確認することも可能です。
ただし、履歴がこのファイルへ書き込まれるのは、基本的にシェルを終了するタイミングです。メモリ上に保持される件数はHISTSIZEという変数で決まっており、echo $HISTSIZEで自分の環境の設定値を確認できます。
最新のbashでも同じように使える?¶
bashは2025年7月にバージョン5.3がリリースされましたが、履歴展開の基本的な仕様に変更はありません。この記事で紹介した使い方は、最新版でもそのまま有効です。
古いサーバーから最新のディストリビューションまで、同じ知識がずっと通用します。一度手になじませてしまえば、長く使える技術ですよ。
練習できるLinux環境がない場合は?¶
手元にLinux環境がない方は、WSLを使えばWindowsの中に数分でLinuxを用意できます。導入手順はWSLでLinuxを簡単にインストールする方法で解説しています。
また、当サイトInfraAcademyでは、ブラウザ上でLinuxコマンドを試せる学習環境を用意しています。環境構築なしで今すぐ!!を試したい方は、Linuxが基礎から学べるInfraAcademyの紹介記事ものぞいてみてください。
まとめ¶
今回は、Linuxのビックリマーク(!)について解説しました。
Linuxのビックリマーク(!)コマンドは、過去のコマンドをすばやく呼び出して再実行する強力なツールです。操作ミスの修正やコマンドの再利用にとても便利なので、覚えておくと作業効率が格段に上がります。
まずは!!とsudo !!だけでも、今日からの作業がぐっと速くなるはずです。慣れてきたら、!$での引数の使い回しや:pでの安全確認にも挑戦してみてください。
echo 'Hello World!'のようにシングルクォートで囲めば、event not foundエラーも怖くありません。Ctrl+Rとの使い分けまでできるようになれば、ターミナル操作は一気に上級者らしくなります。
この記事で紹介した基本の!コマンドを理解し、普段の作業に取り入れてみてください。コマンド操作がスムーズになり、Linuxの操作がより楽しくなること間違いなしです。
ぜひ試してみて、!コマンドの便利さを体感してみましょう。ビックリマーク以外の基本コマンドも固めたい方は、よく使うLinuxコマンド10選からステップアップしていきましょう!