ターミナルのログを自動保存したい
2011-05-27
LinuxやMacOS Xのターミナルで作業したときに、入力したコマンドやその結果を自動で記録したい。
今までは手動でメモ帳やEvernoteにコピー&ペーストしてたけど、さすがにコマンドごとにコピペするのは面倒。 自動で保存する方法を調べてみた。
script コマンド
昔からあるスタンダードな方法。 script [ログファイル名]で保存を開始し、exitもしくはCTRL+Dで保存終了。 ファイル名を省略するとtypescriptというファイルに出力される。
$ script
Script started, output file is typescript
$ ls -l
total 504
drwx------+ 14 machu staff 476 5 28 09:11 Desktop/
drwx------+ 54 machu staff 1836 5 1 12:09 Documents/
drwx------+ 47 machu staff 1598 5 26 22:13 Downloads/
drwxr-xr-x@ 13 machu staff 442 5 26 10:48 Dropbox/
$ exit
Script done, output file is typescript
ログファイルをcatコマンドで表示すると、先ほどの記録 (ls -lコマンドの実行)が確認できる。
Script started on Sat May 28 09:19:19 2011
$ ls -l
total 504
drwx------+ 14 machu staff 476 5 28 09:11 Desktop/
drwx------+ 54 machu staff 1836 5 1 12:09 Documents/
drwx------+ 47 machu staff 1598 5 26 22:13 Downloads/
drwxr-xr-x@ 13 machu staff 442 5 26 10:48 Dropbox/
$ exit
Script done on Sat May 28 09:19:37 2011
ログファイルにはターミナルへの出力内容が、制御文字を含めてそのまま出力される。 そのため、残念ながらテキストエディタでは開くと可読性が落ちる。
$ less typescript
Script started on Sat May 28 09:19:19 2011
ESC_machu@macbook:~ESC\ESC[1;34m[machu:~]$ESC[0m ls -l
total 504
drwx------+ 14 machu staff 476 5 28 09:11 Desktop/
drwx------+ 54 machu staff 1836 5 1 12:09 Documents/
drwx------+ 47 machu staff 1598 5 26 22:13 Downloads/
drwxr-xr-x@ 13 machu staff 442 5 26 10:48 Dropbox/
ESC_machu@macbook:~ESC\ESC[1;34m[machu:~]$ESC[0m exit
Script done on Sat May 28 09:19:37 2011
.zshrc などに書いておけば、シェルの起動時に自動的に保存することもできそう。 詳しくはコアテクの路地 - 作業ログの取り方などを。
screen コマンドのログ
screen コマンドを使っている場合は、screen側でログを記録することもできる。
CTRL+Aの後に大文字の「H」で記録を開始し、もう一度同じコマンドで記録終了。 また、 .screenrcコマンドに以下のように書いておけば、自動的にログを記録してくれる。 「deflog on」が自動保存の設定で、「logfile [ファイル名]」が保存先のファイル名。
deflog on
logfile "logs/screen-%Y%m%d-%n.log"
ログファイル名には年月日+ウインドウ番号が含まれる。
$ ls -l logs
total 312
-rw-r--r-- 1 machu staff 3899 5 28 09:27 screen-20110528-0.log
-rw-r--r-- 1 machu staff 6089 5 28 09:27 screen-20110528-1.log
ログファイルの中身は script コマンドと同様に、制御文字が含まれる。 表示するには cat コマンドを使う。
ちなみに、開いているウインドウと同じ番号のログファイルを開くと、無限ループに突入しファイルサイズが一気に大きくなるので注意。 (表示しているログの内容がログに追記され、それをまた表示しての繰り返し)
screen コマンドのハードコピー
ログに制御文字を含みたくない。テキストエディタで開きたいというときには、 screen のハードコピーが使える。 CTRL+Aの後に小文字の「h」で、現在の画面の内容をテキストに書き出してくれる。 ファイル名は hardcopy.0 (数字の箇所はウインドウ番号)で、ホームディレクトリに出力される。
$ vim app/models/user.rb
# vimが起動されている状態でCTRL+A hを押す
Screen image written to "hardcopy.0".
ログファイルには制御文字を含まないので、テキストエディタでも表示できる。 ちゃんとvimのフッタ部分も表示されている。
$ less ~/hardcopy.0
2 include Mongoid::Document
3 # Include default devise modules. Others available are:
4 # :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
(中略)
45 end
~
~
app/models/user.rb [Rails][iso-2022-jp][unix] 45,1 All
"app/models/user.rb" [converted] 45L, 1451C
ただしhardcopyでは、現在ウインドウに表示されている部分しか記録されない。 WindowsのPrintScreenに似ている。 そういった特性があるので、自動保存もできない模様。
まとめ
screenを使っていなければscriptコマンド。 screenを使っていて、ログに制御文字が含まれてもよいならログ機能 (deflog) が使える。 制御文字を含みたくなければ、ハードコピーになる。 ただし、ハードコピーだと、現在の描画部分しか記録されない。
どれも一長一短。 自動保存してEvernoteに送るには、何を使うのが良いのだろうか…。 screen + ログで記録をとって、後から制御文字だけ削除とか?
追記
id:y0sh1kawさんより、コメントをいただいた。
screenのhardcopyは-hをつければスクロールバックバッファ全体を保存できますよ〜。
CTRL+a hでハードコピーをとるのではなく、CTRL+a :(コロン)でコマンドモードに入り、以下のように入力する。
:hardcopy -h test.log
Screen image appended to "test.log".
以下の条件だったら、制御文字を含まずにいい感じでログが保存できた。
- zshでRPROMPTを使っていない
- 出力結果に日本語(マルチバイト文字?)が含まれない
毎回ログファイル名を入力しないといけないのは、ちょっと面倒。 終了時に自動的に保存してくれるといいのにね。
-hを指定したハードコピーの取り方は、以下のページも参考になった。