t-hom’s diary

主にVBAネタを扱っているブログ…とも言えなくなってきたこの頃。

Raspberry Piの構成変更をScriptコマンドで記録する

今回の記事は完全に自分の備忘録用である。

LinuxにはScriptというコマンドがあり、これを使うとコマンドラインでの入出力をテキストログに記録してくれる。
仕事では監査対応で使ったりするが、Raspberry Piの変更管理にも使えるんじゃないかと思ったのでやってみた。
構成変更をロギングしておけば将来ぶっ壊れたときに環境を再構築しやすくなる。

使い方は、script ファイル名を実行するだけ。
そのあと普通にコマンドを叩いて、おわったらexitすれば操作がファイルに記録される。

これは便利と思って早速使ってみたのだが、vimで普通に開いてみたところ制御文字がばっちり記録されてて読みづらい。
f:id:t-hom:20210801083757p:plain

このログはlessコマンドに-rオプションを付けることで綺麗に読むことができる。
less -r ~/20210801.log
f:id:t-hom:20210801083949p:plain

カラーもついてるので一瞬実際のコマンド画面かと思ったけどログだった。

さて、これをファイル出力して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;
}


ところが実際にやってみると次のとおり日本語が文字化けする。
f:id:t-hom:20210801084720p:plain

これを解決するヒントはこちらに合った。
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 ファイル名で読むと実行したコマンドがそのまま表示されるので、作業エビデンスとしての意味合いを持たせたいなら生ログを残しておくのが吉だと思う。

以上

当ブログは、amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイト宣伝プログラムである、 Amazonアソシエイト・プログラムの参加者です。