pipipipi.net

pipipipi.net

約5分で読めます

scriptコマンドで端末操作を自動ログ記録する(bash tmux)

scriptコマンドで端末操作を自動ログ記録する(bash tmux)

ターミナルの操作履歴をとるためにscriptを使ってますが、いちいち起動するのが面倒なので、 .bashrc に追加しようといろいろ試したところ、現状は以下に落ち着きました。 ~/oplog/に60日間操作履歴ログが残るようになります。

tmuxの場合、ペインごとにファイルが分かれて保存されます。 scriptが実行されているのでexitは2回しなければターミナルは閉じません。 今のところそんな手間ではなくて、Ctrl + dを2回押してパパっと消すことが多いです。

完成スニペット

以下をそのまま .bashrc に追加して、ターミナルを立ち上げなおしてください。

# ===== 再帰防止(最重要)=====
if [ -n "$OPLOG_ACTIVE" ]; then
    return
fi
export OPLOG_ACTIVE=1

# 対話シェルのみ
if { [ -n "$PS1" ] || [ "$TERM_PROGRAM" = "vscode" ] || [ -n "$SSH_TTY" ]; }; then
    mkdir -p ~/oplog
    find ~/oplog/ -type f -mtime +60 -delete
    HOST=$(hostname -s)
    USER=$(whoami)
    if [ -n "$TMUX" ]; then
        SESSION=$(tmux display-message -p '#S')
        PANE=$(echo "$TMUX_PANE" | tr -d '%')
        PREFIX="tmux_${SESSION}_pane${PANE}"
    else
        PREFIX="normal"
    fi
    LOG=~/oplog/"${PREFIX}_$(date '+%Y%m%d_%H%M%S').log"
    echo "=== START script: $LOG ==="
    script -afq "$LOG"
    RET=$?
    echo "=== END script: $LOG (rc=$RET) ==="
fi

構造

① OPLOG_ACTIVE による再帰防止

script コマンドは新しいシェルを起動してその中で作業を記録します。そのシェルが .bashrcを再読み込みすると、また script が呼ばれ、無限にネストします。

OPLOG_ACTIVEを環境変数として設定しておき、既に設定済みなら即 return することでこれを防ぎます。 tmuxを使わない場合は、環境変数がなくてもうまく動いてましたが、tmuxを使うと無限ループしたりしたので導入しました。

② 対話シェルの判定

PS1 が設定されているのは通常の対話シェル、TERM_PROGRAM=vscode は VS Code の統合ターミナル、SSH_TTY は SSH セッションです。3つのいずれかに該当する場合だけログを記録します。

スクリプト実行時(bash hoge.sh)はこれらが設定されないので、バッチ処理の出力はログに混入しません。

③ tmux 配下でのファイル名生成

$TMUX が設定されていれば tmux セッション内にいることが確認できます。tmux display-message -p ‘#S’ でセッション名を、$TMUX_PANE でペイン番号(%6 のような形式)を取得し、tr -d ’%’ で % を除去した数字だけを使います。

結果、tmux_multiagent_pane6_20260626_142530.log のような名前になり、どのセッション・ペインの記録かが一目でわかります。tmux 外では normal_20260626_142530.log となります。

④ scriptの出力抑止と開始・終了時のファイル名 echo

起動時と終了時にログファイルのフルパスを出したかったので、この形になりました。 -qを指定しない場合は、開始時にはログファイルパスは出ますが終了時には出ません。開始・終了時の出力フォーマットを合わせたかったので、-qを指定して script 自身のメッセージを抑止し、自分でファイルパスを出しています。

「どこにログが保存されたか」がターミナルに残るので、後から cat ~/oplog/tmux_…_2026…log でそのまま参照できます。終了時には script の終了コード(rc=0 が正常終了)も表示します。すぐに操作ログを対比したいときもあるので、終了時にもパスを出すようにしています。

⑤ 60日超のログ自動削除

-mtime +60 は「最終更新時刻が60日より前のファイル」を意味します。新しいシェルが起動するたびに実行するので、溜まったログが自動的に片付きます。

操作ログを出力したくない場合

ターミナル起動して、操作ログに残したくない操作をする場合は、Ctrl + dですぐに終了させます。 APIキーやパスワードが表示された場合も一緒で、Ctrl + dで記録を止めて、すぐにログファイルから消します。

その他

tmux 自体の基本操作についてはtmuxチートシートにまとめています。

関連記事