Linux / コマンド / history - コマンド実行履歴の確認

Bashのhistoryコマンドは、現在のシェルが記憶している以前のコマンドを番号付きで表示し、必要な項目を検索・再実行・削除したり、履歴ファイルと同期する際に使用します。最近のコマンドだけを見たい場合はhistory 20、特定の文字列を探す場合はhistory | grep '検索キーワード'、入力中に素早く探したい場合はCtrl+rを使用できます。

historyはBashの組み込みコマンドです。この記事の説明はBashを基準にしており、ZshやFishなど他のシェルでは履歴ファイルや設定方法が異なる場合があります。

historyコマンドとは?

Bashは対話型シェルでユーザーが入力したコマンドをメモリ内の履歴リストに保存します。historyはこのリストを確認・修正し、HISTFILEが指す履歴ファイルを読み書きできるコマンドです。

基本の履歴ファイルは通常~/.bash_historyです。Bashが起動する際にこのファイルを読み込み、メモリ内に履歴リストを作成し、シェルが正常に終了する際に現在の履歴をファイルに保存します。詳細な動作はGNU BashのHistory Facilitiesドキュメントで確認できます。

コマンド履歴は便宜のための機能であり、セキュリティ監査ログではありません。ユーザーが項目を削除でき、シェルが異常終了したり、履歴設定がオフになっている場合は保存されないことがあります。

基本的な使い方

オプションなしで実行すると、現在の Bash セッションの履歴を番号付きで出力します。

history

出力例は次の通りです。

  241  apt update
  242  systemctl status ssh
  243  journalctl -u ssh
  244  history

最後の 20 件のように最近の履歴の一部だけを確認するには、数字を指定します。

history 20
形式 機能 注意点
history n 最近の n 件の項目を出力 現在のシェルのメモリリストを基準にします。
history -c 現在の記録リスト全体を削除 他のシェルセッションやファイルの状態は別に考慮する必要があります。
history -d 番号 指定した項目を削除 削除する番号が正しいかまず確認します。
history -a 今回のセッションの新しい項目をファイルの末尾に追加 HISTFILEが設定されている必要があります。
history -n ファイルの新しい項目を現在のリストに追加 別のセッションで追加した履歴を取得する際に便利です。
history -r 履歴ファイル全体を現在のリストに追加 既にある項目と重複する可能性があります。
history -w 現在のリストで履歴ファイルを上書き 複数のターミナルが開かれている場合、他のセッションの履歴に影響を与える可能性があります。
history -p 表現式 履歴展開の結果のみを出力 実行前に ! の拡張結果を確認する際に便利です。
history -s コマンド コマンドを実行せずに履歴に追加 現在の履歴リストの最後の項目に入ります。

各オプションの正確な定義と戻り値の状態については、GNU BashのHistory Builtinsドキュメントを参照できます。

以前のコマンドを検索する

grepでリストをフィルタリングする

履歴の中で特定の文字列を含む行だけを見たい場合は、grepとパイプを組み合わせて使用します。

history | grep 'systemctl'

大文字小文字を区別しないようにするには、grep -iを使用します。

history | grep -i 'nginx'

この方法は結果を確認するのに便利ですが、出力に現在検索中のコマンドまで結果に含まれる場合があります。

Ctrl+rで入力中に検索する

Bashが基本的なEmacs編集モードを使用する場合、Ctrl+rで前のコマンドを逆方向インクリメンタル検索できます。検索する文字を入力するたびに、最新の一致項目が表示され、Ctrl+rを再び押すと、それより古い次の結果に移動します。

  • Enter: 表示されたコマンドを実行します。
  • 左・右方向キー: 検索を終了してコマンドを編集します。
  • Ctrl+g: 検索をキャンセルして元の入力に戻ります。

実行する直前に方向キーで検索を終了してコマンドと引数を確認する習慣は安全です。検索方法はGNU Readlineのコマンド履歴検索のドキュメントに説明されています。

前のコマンドを再実行する

感嘆符を使った履歴展開

対話型Bashでは、!で始まる履歴展開(history expansion)を使って前のコマンドを呼び出すことができます。

表現式 意味 例
!! 直前のコマンド sudo !!は直前のコマンドの前にsudoを付けます。
!125 記録番号125のコマンド 番号はhistoryの出力で確認します。
!-3 現在の位置から三つ前のコマンド 最近のコマンドを相対的な位置で選択します。
!ssh sshで始まる最新のコマンド 同じ接頭辞のコマンドが多い場合、予想と異なる項目が選択されることがあります。
!?nginx? nginxを含む最新のコマンド コマンドの途中の文字列で検索します。
^前^新しい値^ 直前のコマンドの最初の一致文字列を置き換えて実行 短いタイプミスを修正して再実行する際に使用します。

履歴展開は基本的に対話型Bashで有効であり、非対話型シェルスクリプトでは基本的に行われません。詳細な文法はGNU BashのHistory Expansionドキュメントで確認できます。

実行前に展開結果を確認する

!番号と!文字列は、見つかったコマンドをすぐに実行できるため、削除・権限変更・システム終了コマンドが履歴にある場合は特に注意が必要です。history -pに式を引用符で囲んで渡すと、実行せずに展開結果のみを確認できます。

history -p '!!'
history -p '!ssh'

Readlineを使用するBashでは、以下のオプションを設定すると、履歴展開の結果をすぐに実行せずに、まず編集バッファに表示することができます。

shopt -s histverify

番号が変わりやすい複数の端末環境では、Ctrl+rで内容を確認してから実行する方法の方がより安全な場合が多いです。

コマンド履歴を削除する

特定の項目を削除

まずhistoryで番号を確認し、その後-dオプションで該当項目をメモリの履歴リストから削除します。

history -d 125

現在のBashが範囲削除に対応している場合は、開始番号と終了番号を指定することもできます。

history -d 120-125

削除結果を現在の履歴ファイルに反映させるには、リストを確認した後にhistory -wを実行できます。ただし、他の端末セッションが後で終了し、以前の履歴を再びファイルに書き込む可能性があるため、複数セッションが開いていないか確認する必要があります。

現在のリスト全体を削除

-c オプションは、現在のシェルのメモリにある履歴リストをすべて消去します。

history -c

履歴ファイルまで現在のリストで更新するには、history -w の動作を理解したうえで使用する必要があります。履歴の削除はシェルの履歴のみが対象であり、システムログ、監査ログ、バックアップや他の端末の履歴まで削除するわけではありません。

履歴ファイルと複数の端末セッション

Bash は、実行中の各シェルごとに別々のメモリ履歴リストを持ちます。デフォルトの動作では、他の端末で直前に実行したコマンドは現在の端末の history に即座に表示されない場合があります。

コマンド 履歴ファイルと現在のセッション間の動作
history -a 現在のセッションでまだファイルに保存していない新しい履歴をファイルの末尾に追加します。
history -n 履歴ファイルから現在のセッションがまだ読み込んでいない新しい行をメモリリストに追加します。
history -r 履歴ファイルの内容全てを現在のメモリリストの後ろに追加します。
history -w 現在のメモリリスト全体で履歴ファイルを上書きします。

他の端末の新しい履歴を取得するには、まずその端末でhistory -aとしてファイルに追加し、現在の端末ではhistory -nとして読み込みます。history -nは追記された新しい行を読む機能です。他のセッションによるファイルの上書きや短縮がある場合は、単純な追記同期とは同じに扱わないでください。

history -a
history -n

シェル終了時に履歴ファイルを上書きせず、新しい項目を追加するにはhistappendオプションを使用できます。

shopt -s histappend

この設定を使い続けるには、ユーザーの~/.bashrcに追加します。複数の端末でプロンプトごとに自動同期するようPROMPT_COMMANDを設定する方法もありますが、既存の設定やプログラムがこの変数を使用している場合があるので、現在の値を確認せずに上書きしてはいけません。

履歴関連の環境変数設定

変数 役割
HISTFILE 履歴を保存するファイルのパスです。一般的なデフォルト値は~/.bash_historyです。
HISTSIZE 現在のシェルのメモリ履歴リストに保持する最大コマンド数です。
HISTFILESIZE 記録ファイルに保持する最大サイズを行単位で制限します。
HISTCONTROL 空白で始まるコマンドや連続した重複コマンドを記録しないなどの保存ルールを設定します。
HISTIGNORE 記録から除外するコマンドパターンをコロンで区切って指定します。
HISTTIMEFORMAT history 出力に表示する日付と時刻の形式を指定します。

変更前に現在の設定値と~/.bashrcをバックアップしてください。保持上限を今より小さくすると、古い履歴が失われる場合があります。例えば次の設定は、メモリには5,000件のコマンド、履歴ファイルには10,000行という上限を設定し、空白で始まるコマンドと重複コマンドを減らし、日付と時刻を表示します。

HISTSIZE=5000
HISTFILESIZE=10000
HISTCONTROL=ignoreboth:erasedups
HISTTIMEFORMAT='%F %T '
shopt -s histappend

HISTTIMEFORMATは表示形式を指定するもので、記録されていない過去の実行時刻を復元する機能ではありません。設定を戻す際は今回変更した行だけを元の値に戻し、他の設定を上書きしません。継続して適用するには、上記の設定を~/.bashrcに追加した後、新しいBashを開始するか、設定ファイルを再読み込みします。

source ~/.bashrc

HISTCONTROL=ignorebothはignorespaceとignoredupsを一緒に適用します。erasedupsは新しく追加するコマンドと同じ過去の項目を履歴リストから削除します。変数ごとの詳細ルールはGNU Bashの変数ドキュメントで確認できます。

コマンドの記録とセキュリティ

パスワード、APIキー、トークンや秘密鍵の内容をコマンドライン引数として入力すると、シェルの履歴だけでなく、実行中のプロセス情報やその他のログに漏れる可能性があります。機密情報はコマンドラインに直接入力せず、プログラムが提供する標準入力、安全な認証情報ストレージ、またはアクセス権限が制限された設定ファイルを使用することを推奨します。

HISTCONTROLにignorespaceが設定されている場合、スペースで始まるコマンドを履歴から除外できます。しかし、設定が実際に有効になっているかに依存する必要があり、他のログまで防ぐわけではないので、機密情報保護の方法としてのみ信頼してはいけません。

printf '%s\n' "$HISTCONTROL"
printf '%s\n' "$HISTFILE"

history -dやhistory -cで項目を削除しても、他のシェルセッション、バックアップ、監査ログやアプリケーションログに同じ情報が残る可能性があります。認証情報が露出した場合、履歴の削除だけでなく、該当のパスワードやトークンを廃棄し、新しく発行する必要があります。

よく発生する問題

他のターミナルの最新コマンドが見えません

各Bashセッションは独立したメモリリストを使用します。コマンドを実行したターミナルでhistory -aを実行し、その後確認するターミナルでhistory -nを実行してみてください。長期的にはhistappendとシェルの初期化設定を検討することができます。

ターミナルを閉じた後、履歴が消えました

HISTFILEが空でないか、または履歴ファイルに書き込む権限があるか、HISTSIZEとHISTFILESIZEが0に設定されていないかを確認してください。シェルが強制終了された場合、終了時の履歴保存処理が実行されていない可能性があります。

history番号が以前と変わりました

履歴番号は固定された識別子ではなく、現在のメモリリスト上の位置です。項目を削除したり、ファイルを再読込して別のセッションの履歴と統合すると、番号が変わることがあります。古い番号を覚えて実行するよりも、検索してコマンド内容を確認する方が安全です。

ZshやFishでも同じ設定を使えますか?

そのまま適用することはできません。historyという名前の機能があっても、履歴ファイルや環境変数との同期方法はシェルごとに異なります。まずprintf '%s\n' "$SHELL"でログインシェルの設定値を確認できます。ただし$SHELLは現在動いているシェルとは限りません。Linuxではps -p "$$" -o comm=などで現在のシェルのプロセスも確認し、その公式ドキュメントを参照してください。

まとめ

historyはBashで以前のコマンドを参照するだけでなく、特定の項目削除、履歴ファイルの読み書き、セッション間同期にも使用できます。日常的な検索にはhistory | grepとCtrl+rが便利で、履歴拡張で再実行する場合は、まずコマンド内容を確認してください。

記録の量と保存方法を変更するには、HISTSIZE、HISTFILESIZE、HISTCONTROL、HISTTIMEFORMAT、histappendを一緒に確認してください。他のコマンドの用途は、Linuxコマンド一覧で作業別に探すことができます。