新人が今後の業務効率化のために色々なTera Termマクロ作ってみた2(ちょっと進んでlog自動化、root昇格マクロ)

#今回の目的
1. マクロの中でlinuxのsuコマンドを使いrootアカウントに昇格
    1. rootアカウントのパスワードも暗号化する

2. マクロの中でlogを取るのも自動化
⇒これでlogの取り忘れもなくなる

###前回の記事の紹介
前回ははじめの一歩ともいえるログインだけ実行するTeraTermのマクロの作り方や説明をしています。[こちら](https://qiita.com/kunutomo22/items/c0bee7aa1cd4dba2dd83)を見てからの方が理解が深まるかもしれないのでお勧めします。(テイのいい宣伝)

#早速マクロのコードを見てみる。
```ruby:Autolog&ChangeRoot.ttl
;接続情報
username = 'XXXX'                                          ;ログインするサーバーのユーザー名
rusername = 'root'                                         ;rootのユーザー名
hostname = 'XXX.XXX.XXX.XXX'                               ;ログインするサーバーのホスト名またはIPアドレス
passwdfile = 'passwd.dat'                                  ;パスワード暗号化ファイル
rpasswdfile = 'rpasswd.dat'                                ;rootアカウントのパスワード暗号化ファイル
portnum = '22'                                             ;port番号の指定
getdir dir                                                 ;Teratermマクロ配置ディレクトリを取得

;log directry
logdir = dir                                               ;文字列変数logdirに取得したdirを入れる
strconcat logdir '\log\'                                   ;文字列変数logdirに付け足す

;there isn't logdirectry
foldersearch logdir                                        ;先ほど文字列操作をしてできたディレクトリがあるかどうか判断する
if result = 0 then                                         ;ディレクトリが無い時、、、
foldercreate logdir                                        ;ホルダーを作る
endif

getpassword passwdfile username userpasswd                 ; パスワード暗号化ファイルからログインユーザーのパスワード取得
getpassword rpasswdfile rusername ruserpasswd              ; パスワード暗号化ファイルからrootユーザーのパスワード取得

msg = hostname                                             ;まず文字列の変数msgに先に定義した文字列の変数hostnameを入れる
strconcat msg ':portnum /ssh /auth=password /user='        ;定義した文字列変数msgの後にさらに文字を付け足す
strconcat msg username                                     ;更に先に定義した文字列の変数usernameを付け足す
strconcat msg ' /passwd='                                  ;またまた文字を付け足し
strconcat msg userpasswd                                   ;更に先に取得したパスワードである文字列の変数userpasswdを付け足す
strconcat msg inputstr                                     ;ここは要らない気がする??

connect msg                                                ;ここまで作ってきたmsgの文字列を元に接続

;logfile information
getdate logdate '%Y-%m-%d_%H%M%S'                          ;logfileの名前に必要な時間の情報を取得
strconcat logname logdir                                   ;空の文字列変数lognameに前に作ったlogdirを付け足す
strconcat logname logdate                                  ;取得した時間の情報を付け足す
strconcat logname '.log'                                   ;拡張子の.logを付け足す

;create logfile
logopen logname 1 0                                        ;文字をすべてそのままファイルに書き込むようなlogfileを作る

;comand
wait '$'                                                   ;完全に接続されるまで待つ
sendln 'su'                                                ;suコマンドを送信する
wait 'パスワード:'                                          ;rootのパスワードを聞かれるまで待つ
sendln ruserpasswd                                         ;パスワード暗号化ファイルから取得したrootパスワードを送信
wait '#'                                                   ;rootアカウントに完全に昇格するまで待つ
sendln 'cd /'                                              ;ここは自分の好みでrootディレクトリにチェンジディレクトリ

end
;マクロ仕様============================================================================================
;一般ユーザーとしてログインする。
;初回ログイン時は一般ユーザーのパスワードとrootユーザーのパスワードを打ち込む必要がある。
;logはttlファイルの保存されているフォルダのlogというフォルダに保存する。なければ自動でフォルダを作る。
;logのファイル名はYYYY-MM-DD_HMS.log
;logは特殊文字の表示有り
;最初はホームディレクトリでなくルートディレクトリから
```
rootへの昇格やlogとりの自動化をマクロにするとこんな感じ。
マクロの仕様は一番下のコメントアウト部分を参照。
endの上の二行
`wait '#'`
`sendln 'cd /'`
に関しては完全に筆者の好みで何となくルートディレクトリから始まってもらった方が自分は分かりやすいという理由なので必須ではない。
だいたいはコードの中のコメントで簡単に説明してるつもりだが、付け足して説明したい所を説明する。
#なぜ`strconcat logdir '\log\'`なのか
何か後ろにも前にも\がついてて気持ち悪いが、これは`getdir`の仕様でこのコマンドは最後に\を付け足してくれないのでここで付け足すような感じになっている。
#今回の肝、log格納フォルダーがなかった場合
このマクロでは`;there isn't logdirectry`から後は`;log directry`のブロックで作成したlogフォルダのディレクトリ情報と一致するフォルダがない時の挙動を記述している。
やってることはlogフォルダのディレクトリ情報と一致するフォルダを探し無ければ`;log directry`のブロックで作成したlogフォルダのディレクトリ情報と一致するフォルダを作るというもの。
言語化すれば簡単なもののここで押さえておかなければいけない大切なことがある。
###TeraTermマクロのシステム変数
細かいことや他のシステム変数については[TeraTermマクロヘルプの変数説明ページ](https://ttssh2.osdn.jp/manual/ja/macro/syntax/variables.html)を参照して欲しいのだが、ここではこのマクロで使われている`result`について説明する。
####resultの主な役割
このシステム変数には大体の場合、マクロの中のコマンドが失敗したか成功したかそれとも部分的に失敗しているのかで違う値が入る。
今回は`foldersearch`が成功するかしないかでシステム変数`result`に1か0が入るということになる。
因みに前回触れたconectコマンドは部分的に失敗ということもあるので0,1,2の3つの値が入りうるらしい。
#strconcatの嵐!!logファイル名決定部分
全体的にやってることは文字列の変数に付け足していってるだけなのだが押さえておきたいポイントが二つほど。
###いつ取ったlog?そんなあなたにgetdate
`getdate`は`getdate <strvar> [<format> [<timezone>]]`という書式だ。
タイムゾーン指定まではやる人はいないと思うので説明を省く。
今回はformatの部分で`'%Y-%m-%d_%H%M%S'`という指定を行った。この形式だと2020年12月25日12時34分56秒だとすると「2020-12-25_123456」となる。詳細は例によって[TeraTermコマンドリファレンス](https://ttssh2.osdn.jp/manual/ja/macro/command/index.html)を参照してもらいたい。
###意外と忘れるフルパス指定
今回は`strconcat logname logdir`の部分で`;log directry`のブロックで作ったディレクトリ情報を空の文字列変数lognameに付け足すのだが、実はこれを怠るとどいういう挙動になるかというと`logopen`の仕様で面倒くさいことにTeraTermのカレントディレクトリにlogファイルが格納されることになってしまう。(逆に言えばそれでもかまわない人はこの一行は無駄ということになる。)
#次回投稿予告
ここまでくればlinuxのコマンドの知識さえあれば大体のマクロを作れるのですが、飽くまでも一例として自分が作ってみたマクロの数々を載せて簡単な解説をしてみようと思います。