Linuxのscriptコマンドで覚えておくと便利な使い方4個

よくターミナルでの作業ログなどを記録する際に用いられるscriptコマンドだが、オプション自体はあまり多くは無いのだがうまいこと使えれば色々な使い方ができる。 個人的にはよく利用されていると思っていたのだが、あまり周りで使ってる人がいないようなので、とりあえず個人的に知っている使い方についてまとめてみることにした。

1. 基本的な使い方

オプション無しで実行することにより、カレントディレクトリに「typescript」というファイルを作成して作業終了後に操作ログを出力してくれる。

script

指定したファイルに記録する場合は、以下のように引数として出力先のPATHを指定してやればよい。

script PATH
script ./$(date +%Y%m%d_%H%M%S).log # ログ名にタイムスタンプを付与する場合

ログに追記する

オプション無しで実行した場合、既存のファイルがあった場合上書きしてしまう。 追記する場合は、「-a」オプションを付与することで対応できる。

script -a
[root@BS-PUB-CENT7-01 ~]# script
スクリプトを開始しました、ファイルは typescript です
[root@BS-PUB-CENT7-01 ~]# echo aaa
aaa
[root@BS-PUB-CENT7-01 ~]# exit
exit
スクリプトを終了しました、ファイルは typescript です
[root@BS-PUB-CENT7-01 ~]# cat typescript
スクリプトは 2017年05月20日 17時13分53秒
 に開始しました[root@BS-PUB-CENT7-01 ~]# echo aaa
aaa
[root@BS-PUB-CENT7-01 ~]# exit
exit

スクリプトは 2017年05月20日 17時13分58秒
 に終了しました[root@BS-PUB-CENT7-01 ~]#
[root@BS-PUB-CENT7-01 ~]# script -a
スクリプトを開始しました、ファイルは typescript です
[root@BS-PUB-CENT7-01 ~]# echo bbb
bbb
[root@BS-PUB-CENT7-01 ~]#
[root@BS-PUB-CENT7-01 ~]# exit
exit
スクリプトを終了しました、ファイルは typescript です
[root@BS-PUB-CENT7-01 ~]# cat typescript
スクリプトは 2017年05月20日 17時13分53秒
 に開始しました[root@BS-PUB-CENT7-01 ~]# echo aaa
aaa
[root@BS-PUB-CENT7-01 ~]# exit
exit

スクリプトは 2017年05月20日 17時13分58秒
 に終了しましたスクリプトは 2017年05月20日 17時14分04秒
 に開始しました[root@BS-PUB-CENT7-01 ~]# echo bbb
bbb
[root@BS-PUB-CENT7-01 ~]#
[root@BS-PUB-CENT7-01 ~]# exit
exit

スクリプトは 2017年05月20日 17時14分08秒
 に終了しました[root@BS-PUB-CENT7-01 ~]#

指定したコマンドを実行する

Linuxのscriptコマンドでは、以下のようにすることで指定したコマンドの内容のみをログに記録する事ができる。 (BSD系の場合はちょっと指定方法が違うので注意)

script -c 'Command' PATH # Linux
script PATH 'Command' #BSD(Mac OS X)

実行コマンドの終了ステータスをscriptコマンド側で得る場合は、「-e」オプションも付与することで取得可能だ。

script -ec 'Command' PATH
[root@BS-PUB-CENT7-01 ~]# script -c 'ls -l /c' ls.log
スクリプトを開始しました、ファイルは ls.log です
ls: /c にアクセスできません: そのようなファイルやディレクトリはありません
スクリプトを終了しました、ファイルは ls.log です
[root@BS-PUB-CENT7-01 ~]# echo $?
0
[root@BS-PUB-CENT7-01 ~]#
[root@BS-PUB-CENT7-01 ~]# script -ec 'ls -l /c' ls.log
スクリプトを開始しました、ファイルは ls.log です
ls: /c にアクセスできません: そのようなファイルやディレクトリはありません
スクリプトを終了しました、ファイルは ls.log です
[root@BS-PUB-CENT7-01 ~]#
[root@BS-PUB-CENT7-01 ~]# echo $?
2

リアルタイムで書き込みをする

通常、ログファイルへの書き込みはscriptコマンドの実行終了時になるが、「-f」オプションを付与することで即座に書き込みをさせるようにできる。

script -f

開始メッセージを表示させない

ログ取得開始メッセージを非表示にする場合、「-q」オプションを付与する。

script -q
[root@BS-PUB-CENT7-01 ~]# script
スクリプトを開始しました、ファイルは typescript です
[root@BS-PUB-CENT7-01 ~]#
[root@BS-PUB-CENT7-01 ~]# exit
exit
スクリプトを終了しました、ファイルは typescript です
[root@BS-PUB-CENT7-01 ~]#
[root@BS-PUB-CENT7-01 ~]# script -q
[root@BS-PUB-CENT7-01 ~]#
[root@BS-PUB-CENT7-01 ~]# exit
exit
[root@BS-PUB-CENT7-01 ~]#

2.scriptreplayでログを再生する

以前にもここで触れたのだが、scriptコマンドでは、-tオプションで各種操作のタイミングを取得しておくことで、scriptreplayコマンドを使って操作内容を再生することができる。 なお、この機能を利用する際は日本語環境だとうまくいかない(タイムログの中で計算している文字数と合わなくなる)ので、LANG=Cを実行前に行っておくと良いだろう。 以下の例では、log.timeに操作のタイミングを、log.sessionに操作内容を記録している。

LANG=C script -t 2> log.time log.session

記録されたタイミングログと操作ログを組み合わせ、以下のようにscriptreplayコマンドを実行することで、操作内容を再生できる。

scriptreplay -t log.time log.session

3. Teratermログのように、ログにタイムスタンプを付与する

以前ここに書いた内容だが、scriptコマンドで取得したログにTeratermログのようなタイムスタンプを付与する場合は、以下のように出力時にawkを間に入れてやることで対応が可能だ。

script -fq >(awk '{print strftime("%F %T ") $0}{fflush() }'>> PATH)

もしscriptreplayと組み合わせて使用する場合は、以前ここにも書いたのだが、以下のようにコマンドを実行すれば良い。 (ログのタイミングを記録するのがlog.time、ターミナルログ自体はlog.sessionで記述している)

ログ取得時

LANG=C script -fqt 2> log.time >(awk '{print strftime("%F %T ") $0}{fflush() }'>> log.session)

scriptreplay実行時

scriptreplay -t log.time <(cut -c 21- log.session) # タイムスタンプ無しで再生する場合
scriptreplay -t <(awk 'BEGIN{i=0}{cmd="cat log.session|cut -c 21-|tail -c +"i" |head -c "$2"|wc -l";cmd|getline c;i+=$2;print $1,$2+c*20}' log.time) log.session # タイムスタンプ付きで再生する場合

4. 他のターミナルセッションに操作内容を表示させる

ログの出力先を他のターミナルセッションにすることで、現在操作中の内容を他のセッションの利用者(別にssh接続している人間)に見せる事ができる。 詳細については以前こちらに記述しているので、そっちを参照。

script -fq /dev/pts/n

大体こんなところだろうか。 他にも色々と使い方があると思うが、ひとまずこんな感じで。