ターミナルのログを自動保存したい
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を指定したハードコピーの取り方は、以下のページも参考になった。