`expect` で絞めていただこ - shellscript の実行途中で求められるパスワード入力を自動で
と言うお話.
設定用 shellscript を走らせていて,途中,度々求められるメールやパスワードの入力がどうにかならないものか,と思うようになってきました.
このために結局マシンの前を離れられない.
何のためにスクリプト用意して作業を自動化しているのか,
煩雑な作業を shellscript に任せて自動化してやっほい,という企みもこれではほっとんど意味がないじゃない.
...と彷徨い,ほどなくして expect
というコマンドがあることを知ります.
そんなとき、毎回パスワードを入力するのは面倒!(略)という問題を解決するのがexpectというコマンドです。
コマンドの返答を識別して次の入力を自動的に行うコマンド
今回これを使ってみたので,備忘録.
% sw_vers ProductName: Mac OS X ProductVersion: 10.12.2 BuildVersion: 16C67
こんな処理があった場合
shellscript の中に,このような記述があるとします.
path="/usr/local/bin/zsh" chsh -s ${path}
ログインシェルを変更しようとしているわけですが,ここに来ると確認のパスワードを求めて,処理は止まり待機状態になります.
こんな感じで.
<user>
の部分は,各自実際のアカウント名が入ります.;
/usr/local/bin/zsh Changing shell for <user>. Password for <user>:
Password for <user>:
にカーソルがあるので,ここにパスワードを入れる必要があります.
これを exepect
使ってやると.
こうなります
password="oooooooooo" # お好きなパスワード等を定義. expect -c " spawn chsh -s "/usr/local/bin/zsh" expect \"Password for $(id -u -n):\" send \"${password}\n\" interact "
こうすれば expect
内でパスワードを渡してくれるので,席を離れて安心してコーヒーを淹れに行くことができるようになります.
意識低いメモ
必要最低限は
expect
は他にも色々できることがあるようですが,自身のケースにおいては上述の要素で十分かと考えてます.
かなり乱暴で稚拙ではありますが,自分の言葉で.;
spawn
入力(対話)を求めてくるコマンドの処理を,そのまま記載.expect
こちらの入力を待つ時に出力される文字列を,そのまま記載.send
入力させたい文字列.パスワード等.intract
画面に内容を出力.
「spawn
を処理する時に聞いてくる expect
に対し,自動で send
を入力してもらう.」
そんなイメージ.
さらに詳細な説明については,既に優れたサイトやエントリ等があるので,そちらを参照頂くとして.
ちなみにインストール using homebrew
brew install expect
有り難い.*1
expect
は homebrew の dupes の中なので,導入していない場合は,インストール前に tap をば.
シバンは #!/bin/bash
,shellscript なので -c
オプションで ""
クォートの中に書く
何変なこと言ってるの思われるかもしれませんが.
スクリプトで expect
のみならば,#!/usr/bin/expect
として使用することができるのだそう.
Expect は、 cmdfile を読み込み、実行するコマンドのリストを得る。 Expect は、#! 表記をサポートする OS で、先頭行に
#!/usr/local/bin/expect -f
と書いておいて実行させることもできる。
via. Man page of EXPECT
ここで言う,"いつものように" shellscript で使う時は,-c
オプションを付け,処理内容全体を "
で囲んで使うるのだそう.
expect -c は、「これからexpectの処理を開始しますよー」という宣言をしています。
\"
ダブルクォート は,エスケープ必要
spawn
以外.
時にエスケープなしでダブルクォート使って記述している情報もあって,どうもスッキリしない感があったのですが,実際に動かして,やはり必要ってことで.
このコード見て,見た目に惚れたのですが,どうも駄目な様子.
ちなみに,このエスケープ必須は shellscript だからと言うことらしいです.#!/usr/bin/expect
で書く場合はこういったエスケープ不要っぽい?
結構,普段通りに書けるっぽい
先述の例で変数やコマンド置換 command substitution 使ったりしていますけど,結構普通に記述できるみたいで.
ちなみに,$(id -u -n)
はユーザー名を取ってきています.
ここで教えてもらいました.
と言うことで.
今回の作業によって,対話的な処理のために,画面の前でジリジリと待っていなければならない,とか逆に,席離れて戻ってきたら入力待ちで止まっていた,とか,そんなムダな時間を極力減らすことができるようになるんじゃないでしょうか.
はいおしまい.
*1:幾つかオプションをつけているのありましたが,何もなくても特に問題なく.つか,わかっていないだけかもしれませんが笑