ksaitoの日記

日々試したことの覚え書き

手動のオペレーションを自動化する

CUIのプログラムで繰り返し手動のオペレーションが必要な処理が必要な場合には、expectコマンドが便利です。

ログイン時に毎回実行するコマンドを自動化する

ログインした時に毎回実行するなら初期設定用の.profileや.*rcに設定するのが普通ですが、利用するサーバによっては共有のアカウントで設定変更を勝手にできないことがあります。
そういう環境に限ってTERMが設定されていなかったり、利用するコマンドにパスが切れていなかったりすることが多いです。
パスワードは、手動で入力しログイン時に毎回入力するようなコマンドは、expectのスクリプトに記述します。

スクリプト

下記のようなスクリプトを準備します。
[プロンプト文字列]は、ログイン先のプロンプトの文字列に置き換えます。

$ cat ssh-localhost
stty -echo
send_user "Password:"
expect_user -re "(.*)\n"
send_user "\n"
set PW $expect_out(1,string)
stty echo
spawn ssh localhost
expect "continue connecting" {
  send "yes\n"
  expect "password"
  send "$PW"
  send "\n"
} "password" {
  send "$PW"
  send "\n"
}
expect "[プロンプト文字列]"
send "ls\n"
interact
$ 

このスクリプトでは、spawnの前までの処理で、パスワードの入力を求めます。
$PWに入力されたパスワードを格納して使います。
spawnでsshコマンドでローカルホストに接続します。(localhostに接続しても意味無いですがサンプルとして...)
expectで文字列を待ち受けます。
sshの接続では、passwordを聞かれるので入力した$PWを送り返します。
プロンプト文字列が返されたら、普段繰り返し実行するコマンドを入力し制御を戻します。

デバッグ

expectの"-d"オプションを使うとデバッグ情報が表示されます。
スクリプトが予期しない動きをした場合に、このオプションでデバッグします。

間違った使い方

パスワードの入力に使う

パスワードの入力を省略するためにスクリプトにパスワードの直書きをしてはいけません。
sudoを使うことを検討しましょう。

やり直しのきかない作業

何かやり直しがきかない作業のためにexpectを使うのはお薦めできません。
expectはプログラムと同じなのでバグにより取り返しのつかないことになります。