Man On a Mission

システム運用屋が、日々のあれこれや情報処理技術者試験の攻略を記録していくITブログ…というのも昔の話。今や歴史メインでたまに軍事。別に詳しくないので過大な期待は禁物。

【Linux】scriptコマンドで操作ログを取る

過去3回にわたり、Linuxのコマンド履歴を表示するhistoryコマンドの記事を書きました。

【Linux】bashのコマンド履歴数を増やす - Man On a Mission

【Linux】HISTSIZEとHISTFILESIZEの違い - Man On a Mission

【Linux】historyコマンド おまけ - Man On a Mission

historyコマンドを使えば、過去にどのようなコマンドを実行したか、確認できます。
環境変数HISTTIMEFORMATを適切に設定すれば、タイムスタンプも付与されるので、いつ実行したコマンドかもわかります。

しかし残念ながら、そのコマンドの実行結果についてはわかりません。
historyは、あくまでもコマンドの履歴であり、操作ログではないからです。

 では、Linuxで操作ログを取りたい場合、どうしたら良いでしょうか?
CUI限定ではありますが、その回答の一つがscriptコマンドです。

scriptコマンドで操作ログを残す

scriptコマンドは、端末に表示されたもの全てを、ファイルに記録するコマンドです。
(ただし、エディタなど画面書き換えが行われるもの等については、正常に記録できないことがあります。)

以下コマンドの実行により、記録を開始します。

script ファイル名
例:script 20170318op.log

※ファイル名を指定しなかった場合は、カレントディレクトリに「typescript」というファイル名で記録されます。

記録を終了するには「exit」と入力するか、「Ctrl-d」を押します。

なお、上記コマンドでは、実行のたびにファイルが新規作成されます。
既存のファイルを指定すると、過去のログは失われてしまいますのでご注意ください。

既存ファイルに追記したい場合は、aオプションを付けます。

script -a ファイル名

なお、実際にファイルに書き込まれるのは、exitまたはCtrl-dで記録を終了した時です。
コマンド実行ごとに書き込まれたりはせず、記録終了時にまとめてファイルに書き出されるわけですね。

コマンド実行ごとに書き込むようにしたい場合は、fオプションを付けます。

script -f ファイル名

bashのプロンプトに時間を表示してタイムスタンプをつける

さて、scriptコマンドは、端末に表示されるものをファイルに記録するだけのコマンドですので、タイムスタンプなどは付与されません。
タイムスタンプを残したい場合、必要に応じて「date」コマンドを打つという手もありますが、面倒だし忘れがちなので、bashのプロンプトに日付と時刻を表示してしまいましょう。

PS1という環境変数を変更することでプロンプトに日付、時刻を表示できます。
具体的には、「.bashrc」ファイルのPS1の定義に「\D{%F %H:%M}」を追記することで日付、時刻が表示されます。

例:
 PS1='\D{%F %H:%M} \u@\h:\w\$ '

ちなみに、タイムスタンプ後ろの\uはユーザー名、\hはホスト名、\wはカレントディレクトリの表示指定です。
最後の\$は、一般ユーザーだと「$」、rootだと「#」になる例のアレです。
詳細については、「man bash」の「プロンプト」項目を見てください。

【おまけ】別の端末へ操作状況を連携する

ちょっとした小技ですが、scriptコマンドのfオプションを利用して、端末の操作状況を、別の端末上で表示することが出来ます。
操作を行う端末と、その操作を表示する別の端末で、それぞれ以下のコマンドを打ちます。

操作を行う端末:

script -f ファイル名

その操作を表示する別の端末:

tail -f ファイル名

仕組みは単純ですね。

ちなみに、teeコマンドでも同じことができます。
こちらは、操作を表示する端末で「tail -f ファイル名」とするのは同じですが、操作を行う端末では下記コマンドとなります。

bash | tee ファイル名

とはいえ、こんな小技が必要なシーンはかなり限られるでしょう。
まあ、こんな使い方もあるんだ、くらいで一つ。