今回の記事は完全に自分の備忘録用である。
LinuxにはScriptというコマンドがあり、これを使うとコマンドラインでの入出力をテキストログに記録してくれる。
仕事では監査対応で使ったりするが、Raspberry Piの変更管理にも使えるんじゃないかと思ったのでやってみた。
構成変更をロギングしておけば将来ぶっ壊れたときに環境を再構築しやすくなる。
使い方は、script ファイル名を実行するだけ。
そのあと普通にコマンドを叩いて、おわったらexitすれば操作がファイルに記録される。
これは便利と思って早速使ってみたのだが、vimで普通に開いてみたところ制御文字がばっちり記録されてて読みづらい。
このログはlessコマンドに-rオプションを付けることで綺麗に読むことができる。
less -r ~/20210801.log
カラーもついてるので一瞬実際のコマンド画面かと思ったけどログだった。
さて、これをファイル出力してWindows側で保管するには制御文字を実際に消し去らないといけない。
そこで利用させていただいたのが以下の掲示板で紹介されていたコード。
unix.stackexchange.com
#!/usr/bin/perl while (<>) { s/ \e[ #%()*+\-.\/]. | \r | # Remove extra carriage returns also (?:\e\[|\x9b) [ -?]* [@-~] | # CSI ... Cmd (?:\e\]|\x9d) .*? (?:\e\\|[\a\x9c]) | # OSC ... (ST|BEL) (?:\e[P^_]|[\x90\x9e\x9f]) .*? (?:\e\\|\x9c) | # (DCS|PM|APC) ... ST \e.|[\x80-\x9f] //xg; 1 while s/[^\b][\b]//g; # remove all non-backspace followed by backspace print; }
ところが実際にやってみると次のとおり日本語が文字化けする。
これを解決するヒントはこちらに合った。
osksn2.hep.sci.osaka-u.ac.jp
最終コード
UTF-8の処理を組み込んで、コードは最終的に次のようになった。
#!/usr/bin/perl use utf8; binmode STDIN, ":utf8"; binmode STDOUT, ":utf8"; while (<>) { s/ \e[ #%()*+\-.\/]. | \r | # Remove extra carriage returns also (?:\e\[|\x9b) [ -?]* [@-~] | # CSI ... Cmd (?:\e\]|\x9d) .*? (?:\e\\|[\a\x9c]) | # OSC ... (ST|BEL) (?:\e[P^_]|[\x90\x9e\x9f]) .*? (?:\e\\|\x9c) | # (DCS|PM|APC) ... ST \e.|[\x80-\x9f] //xg; 1 while s/[^\b][\b]//g; # remove all non-backspace followed by backspace print; }
使い方
このスクリプトをformatlogという名前で保存し、chmod +x formatlogで実行権限を付け、/usr/local/binへ移動する。
(恒久的に使う為にそうしたけど、一回限りならホームフォルダのままでも良い。その場合はコマンド実行にフルパス指定が必要となる。)
これでformatlog < 入力ファイル > 出力テキストファイルというコマンドで制御コードが取り除かれたファイルが入手できるようになった。
上記の操作もScriptでロギングしたので記しておく。
Script started on 2021-08-01 08:54:50+09:00 [TERM="xterm-256color" TTY="/dev/pts/2" COLUMNS="98" LINES="23"] pi@raspberrypi:~ $ pwd /home/pi pi@raspberrypi:~ $ ls 20210801.log Arduino Desktop Downloads Music Public Templates formatlog 202108010854.log Bookshelf Documents Health Pictures Stage Videos pi@raspberrypi:~ $ chmod +x formatlog pi@raspberrypi:~ $ mv formatlog /usr/local/bin mv: 'formatlog' から '/usr/local/bin/formatlog' へ移動できません: 許可がありません pi@raspberrypi:~ $ sudo mv formatlog /usr/local/bin pi@raspberrypi:~ $ formatlog < 20210801.log > 20210801.txt pi@raspberrypi:~ $ ls 20210801.log 202108010854.log Bookshelf Documents Health Pictures Stage Videos 20210801.txt Arduino Desktop Downloads Music Public Templates pi@raspberrypi:~ $ exit exit Script done on 2021-08-01 08:56:10+09:00 [COMMAND_EXIT_CODE="0"]
注意点
このスクリプトでは制御文字を単純に取り除いてしまうため、コマンド履歴を呼び出して編集するような操作を行った場合は少しおかしいことになる。
例えば、以下のようにsudoをつけ忘れてコマンドが失敗した場合、上矢印キーで履歴を呼び出し、Homeキーで先頭にカーソルを移動した後にsudoを入力し、Endキーで末尾に戻ってEnterで実行するということがある。
pi@raspberrypi:~ $ mv formatlog /usr/local/bin mv: 'formatlog' から '/usr/local/bin/formatlog' へ移動できません: 許可がありません pi@raspberrypi:~ $ sudo mv formatlog /usr/local/bin
この場合、生ログは次のように制御コードが入力される。
]0;pi@raspberrypi: ~ [01;32mpi@raspberrypi[00m:[01;34m~ $[00m mv formatlog /us/[Kr/local/bin mv: 'formatlog' から '/usr/local/bin/formatlog' へ移動できません: 許可がありません ]0;pi@raspberrypi: ~ [01;32mpi@raspberrypi[00m:[01;34m~ $[00m mv formatlog /usr/local/bin [C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[1@s[1@u[1@d[1@o[1@ [C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C ]0;
カラーコードも含むのですごく見づらいけど、なんとなく、[1@s[1@u[1@d[1@oがsudoを示していることがよみとれる。これはコマンドより後に登場するため、単純にスクリプトで変換すると以下のように末尾にsudoが付いてしまうのだ。
pi@raspberrypi:~ $ mv formatlog /usr/local/binsudo
これを防ぐ手立ては不明なので、監査ログを作るようなシチュエーションではコマンド履歴を使わずに全部手打ちするか、生ログを残しておくのが良い。
生ログをless -r ファイル名で読むと実行したコマンドがそのまま表示されるので、作業エビデンスとしての意味合いを持たせたいなら生ログを残しておくのが吉だと思う。
以上