ウェブサイト検索

ExpectスクリプトSSH例チュートリアル


Expectスクリプトは素晴らしいLinux/Unixユーティリティです。私は日常生活で多くのUnixサーバーを扱わなければならず、それが仕事であれ、ホスティングサーバーであれ関係ありません。つまり、私は多くのSSHユーザー、そのパスワード、そしてSUユーザーとそのパスワードを覚えておく必要があります。サーバーの数が多いと、これはかなり面倒になります。そこで、サーバーに自動的にログインするスクリプトを書くことを考えました。最初にこれに取り組んでいたとき、SSHパスワードをどう入力するかで行き詰まりました。通常のUnixシェルには、ログインを促されるときにパスワードを送信する方法がありませんからね。その後、ターミナルを開いて入力を受け付けるプログラムとの対話を自動化できるexpectスクリプトについて知りました。

期待されるスクリプト

Expect Scriptは非常に学びやすく、その名前が示すように、コマンドの出力を解析し、指定した正規表現に一致すると、指定された指示を処理します。

期待されるスクリプトSSHの例

自動的にSSHサーバーにログインし、スーパーユーザーとしてログインし、その後簡単なコマンドを実行するために作成したスクリプトはこちらです。sshsudologin.expect

#!/usr/bin/expect

#Usage sshsudologin.expect <host> <ssh user> <ssh password> <su user> <su password>

set timeout 60

spawn ssh [lindex $argv 1]@[lindex $argv 0]

expect "yes/no" { 
	send "yes\r"
	expect "*?assword" { send "[lindex $argv 2]\r" }
	} "*?assword" { send "[lindex $argv 2]\r" }

expect "# " { send "su - [lindex $argv 3]\r" }
expect ": " { send "[lindex $argv 4]\r" }
expect "# " { send "ls -ltr\r" }
interact

Expectスクリプトに関する重要なポイント

  1. 最初の行に、expectスクリプトがインタープリタとして使用されることが指定されていることに注意してください。
  2. スクリプトのデフォルトタイムアウトは10秒であると予想されるため、ログインプロンプトが表示されるまでに時間がかかる場合のタイムアウトの問題を避けるために、タイムアウトを60秒に設定しました。
  3. expectコマンドに続く正規表現と、次に応答として送信すべき内容に注目してください。最初のYes/Noの選択は、リモートサーバーのキーがまだインポートされていない場合でも失敗しないように追加されています。
  4. 他のサーバーでの期待された正規表現は異なりますが、私のサーバーでは「#」で終わりますが、他のサーバーでは「$」で終わるかもしれませんので、それに応じて編集する必要があります。確認すべき唯一のことは、expectコマンドのための正規表現が一致することです。そうすれば、対応するコマンドやパスワードが送信されます。
  5. 最後のexpectコマンドは、サーバーにログインした後でもコマンドを送信できることを示しています。

ここに、正しいパラメータで上記の期待スクリプトを実行したときの出力があります。

pankaj@Pankajs-MacBook-Pro:~$/Users/pankaj/scripts/sshloginsudo.expect 'journaldev.com' 'pankaj' 'ssh_pwd' 'su_user' 'su_pwd'
spawn ssh pankaj@journaldev.com
pankaj@journaldev.com's password: 
Last login: Sun Jun  9 19:54:17 2013 from c-67-161-57-160.hsd1.ca.comcast.net
pankaj@journal [~]# su - su_user
Password: 
su_user@journal [~]# ls -ltr
total 708
...

期待スクリプトに関する追加のヒント

  1. 期待されるスクリプトは、すべての情報が引数として渡されるため、再利用が可能です。そのため、各引数のエイリアスを作成するのが最善であり、素早くログインしてすべてのパラメータを入力する時間を節約できます。例えば、alias journal="/Users/pankaj/scripts/sshloginsudo.expect 'journaldev.com' 'pankaj' 'ssh_pwd' 'su_user' 'su_pwd'"のようにします。
  2. 引数を渡すには常にシングルクォートを使用するのが最良です。なぜなら、ほとんどの場合、パスワードには特殊文字が含まれており、クォートされていないと奇妙な結果を引き起こす可能性があるからです。

注意: 上記のスクリプトはMac OSおよびLinuxシステムでテストされています。参照: SourceForgeページ

関連記事: