趣旨

Linux系のコマンドを扱っていると対話型のコマンドが多いので expectをつかった自動化についてまとめる。

目次

expectとは

expectはTclの拡張ライブラリで、対話型の入力が必要な時の自動実行ツールで有名です。Tclのプログラムがそのまま使えるらしいのです。

サーバー・クリニック: 期待以上の出来のExpect

http://www.ibm.com/developerworks/jp/linux/library/l-sc1/

Tclの文法などの概要(Wiki)

http://ja.wikipedia.org/wiki/Tcl/Tk

リンク

本家(英語)

http://expect.sourceforge.net/

Tcl

http://www.tcl.tk/

Tcl基礎文法最速マスター

http://pyomeha.blog42.fc2.com/blog-entry-6.html

マニュアルページ

http://www.tcl.tk/man/tcl8.5/

DejaGnu?

DejaGnu?は他のPCをテストするフレームワークです。Expectで書かれており、すなわちTclで書かれているわけです。

http://www.gnu.org/software/dejagnu/

ExpectPy?

TclのかわりにPythonで書かれたライブラリかも http://expectpy.sourceforge.net/

Rubyのexpect.rbの使い方

http://rakuto.blogspot.jp/2006/09/rubyexpectrb.html

http://www.42klines.com/2010/08/14/what-to-expect-from-the-ruby-expect-library.html

Ruby expect 条件文(if文)の書き方

http://oshiete.goo.ne.jp/qa/4864602.html

telnet自動化のサンプル

http://www.webhtm.net/blogger/2008/10/rubyexpect-expectrb.html

リファレンスマニュアル

http://www.ruby-lang.org/ja/old-man/html/expect.html

PHPをつかった例

http://php.net/manual/ja/expect.examples-usage.php

Javaの場合:ExpectJ 

http://expectj.sourceforge.net/

心構え

運用を定型化したほうがよい。たとえば実行した結果をwiki等に反映させるとか。

定型化するときに、対話が必要ではない箇所はシェル化しておいたほうがよい。

理由はexpectのスクリプトを書くよりも、シェルを書いたほうが楽

パスは絶対パスでかいておいたほうがよい。理由は、expect内では、シェルの変数とかが使えなかったりするから。

exceptをつかうファイルは普段は暗号をかけ、アクセスできる権限を絞っておくことにしたほうがよい

ファイルの暗号化

[Linux] ファイルを暗号化する方法あれこれ

http://ameblo.jp/itboy/entry-10484615897.html

脆弱性チェック

テキストファイルに暗号化をかけずにパスワードで保管しているのはよくないので自主的に脆弱性について検査しておくこと

Crack/Cracklib

http://dropsafe.crypticide.com/article/1019

逆引き

使用する言語の宣言をする

#!/usr/local/bin/expect -f   

               (パスは環境によって変わります。)

10秒間応答がなければ終了させる

set timeout 10

expectコマンド内でtelnetを実行

spawn telnet 10.1.1.1     #expectコマンド内でtelnetを実行

Password: 文字列が帰ってきたら

expect "Password: "

ログインパスワードaaaを入力

send -- "aaa\n"

expectの終了

expect eof

引数の確認

http://blogs.yahoo.co.jp/eguchium/50663261.html

複数の質問を想定

sshは1度目と2度目以降では質問がことなるので、その場合の記述例

expect \"Are you sure you want to continue connecting (yes/no)?\" {
   send \"yes\n\"
   expect \"work@srv01's password:\"
   send \"password\n\"
} \"work@srv01's password:\" {
   send \"password\n\"
}

ユーザの入力を促す

interact

サンプルコード

パスワードを更新するための簡単なExpectプログラム

# Invoke as "change_password <user> <newpassword>".

  package require expect
      # Define a [proc] that can be re-used in many
      #    applications.
  proc update_one_password {user newpassword} {
      spawn passwd $user
      expect "password: "
      exp_send $newpassword\n
          # passwd insists on verifying the change,
          #    so repeat the password.
      expect "password: "
      exp_send $newpassword\n
 }
 eval update_one_password $argv

Expectの自動化にGUIの外見をもたせる

package require Tk

  frame .account
  frame .password
  label .account.label -text Account
  entry .account.entry -textvariable account
  label .password.label -text Password
      # Show only '*', not the real characters of
      #    the entered password.
  entry .password.entry -textvariable password -show *
  button .button -text "Update account" -command {
      update_one_password $account $password
  }
  pack .account .password .button -side top
  pack .account.label .account.entry -side left
  pack .password.label .password.entry -side left

interactをつかったサンプル

set CTRLZ \e032
interact {
	 -reset $CTRLZ {exec kill -STOP 0}
	 \e001    {puts "you typed a control-A\en";
		  send "\e001"
		 }
	 $       {puts "The date is [exec date]."}
	 \e003    exit
	 foo     {puts "bar"}
	 ~~
}

putsをつかったサンプル

puts $time

この辺はTclのコマンドをしらべたほうがいい

Tclコマンド

http://www.tcl.tk/man/tcl8.5/TclCmd/contents.htm

正規表現をつかったサンプル

regexp {([0-9][0-9]:[0-9][0-9]:[0-9][0-9])} $expect_out(buffer) _ time

if文をつかったサンプル

if {[llength $argv] != 1} {
   puts stderr "Usage: daytime host"
   exit 1
}

未調査なコマンド

dislocate

プロセスをやめたり、名前付きのプロセスにリモートで再接続することができるかも

cryptdir

ディレクトリ内のファイルを暗号化するのにつかえるのかも

decryptdir

kibitz

2人で1つのプロセスを触る時につかうのかも

mkpasswd

パスワード自動生成

passmass

複数台のDBのパスワード変更をおこなうことができるかも

tknewsbiff

おしらせがあったらポップアップウィンドウを開くのかも

unbuffer

出力をみたくない場合につかうのか?

xkibitz

1つのプロセスを複数のターミナルで扱うときにつかうのかも

留意点

後々知ったことではあるが SSHではRuby/PythonなどのSSHライブラリを使うべきで、パスワードではなく証明書ログインをするべき。

だが、やりすぎると、自分の家の中のドアに全部鍵をつけるがごとくになりかねないので、そこはバランスをとろう

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS