- PR -

対話的なプログラムを自動化(expect,interact)

投稿者投稿内容
abi
会議室デビュー日: 2008/10/21
投稿数: 4
投稿日時: 2008-10-21 13:31
はじめまして、Linux経験1年目の初心者です。
現在、CSRの作成など対話的なプログラムを自動化させたいと思い、Expectでスクリプトを作成しています。
入力項目が決まっている場合は、
expect "xxxxx" {send "yyyy\r";exp_continue}
で自動入力させ、その時々で違う項目は手入力させたいと思っています。
しかし、スクリプトの途中でexpectとinteractを併用するようなスクリプトが書けません。

例えば、
Enter Pass Phraseが表示されたら、手入力。
→?
Country Nameが表示されたら、JPを自動で入力。
→expect "Country Name" {send "JP\r";exp_continue}    
Common Nameが表示されたら、手入力。
→?
手入力が終わったらまたexpectで自動入力させる。
といったようにexpectとinteractを、画面に表示された内容で切り替えたいのですが、
うまくいきません。

自分では
expect "Enter Pass Phrase" {interact}
expect "Country Name" {send "JP\r";exp_continue}
と書いてみたのですが、"JP"が入力されず、止まってしまいます。

わかりにくい説明で申し訳ありませんが、ご教授いただければ幸いです。
宜しくお願い致します。

[ メッセージ編集済み 編集者: 未記入 編集日時 2008-10-21 13:49 ]

[ メッセージ編集済み 編集者: 未記入 編集日時 2008-10-21 13:50 ]
あるかな
大ベテラン
会議室デビュー日: 2003/11/04
投稿数: 245
投稿日時: 2008-10-21 15:29
こんにちは。

たしか分岐の記述はこんな感じだと思うんですが。
1つの expect 内で指定文字列が現れるまで、次フェーズに移行しなかったと思います。

コード:

expect {
"Enter Pass Phrase"
{interact}
"Common Name"
{interact}
"Country Name"
{send "JP\r";exp_continue}
}



#コードを BB コードで修正。

[ メッセージ編集済み 編集者: あるかな 編集日時 2008-10-21 15:31 ]
abi
会議室デビュー日: 2008/10/21
投稿数: 4
投稿日時: 2008-10-21 16:07
あるかな様

早々のご回答ありがとうございます。
教えていただいたコードですが、既に試したことがありました。
その場合でもやはりうまくいきませんでした。

私が書いて失敗したスクリプトは以下になります。
-----------------------------------------------------------------
#!/usr/bin/expect --
set timeout -1
spawn openssl req -new -key server.key -out server.csr
expect {
"Enter pass phrase for server.key:" {interact} ←手入力可能
"Country Name" {send "JP\r";exp_continue}    ←ここで止まってしまう
"State or Province Name" {send "Tokyo\r";exp_continue}
"Locality Name" {send "xxxx\r";exp_continue}
"Organization Name" {interact}
"Organizational Unit Name" {interact}
"Common Name" {interact}
"Email Address" {interact}
"A challenge password" {send "\r";exp_continue}
"An optional company name" {send "\r";exp_continue}
}
----------------------------------------------------------------------

Googleで検索してみてもexpectについてのページって少ないですし、参考書も洋書になってしまいます。
どう書き換えればよいかご存知な方いらっしゃいませんか?
あるかな
大ベテラン
会議室デビュー日: 2003/11/04
投稿数: 245
投稿日時: 2008-10-21 16:35
勘違いをしているのか、わかりませんが。
expect 命令文は、1つにつき、1レスポンス分の挙動を記述します。
その為、「Enter pass phrase for server.key」が出現した時点で、
-----
...
spawn openssl req -new -key server.key -out server.csr
expect { ... }
-----
ここまで処理が流れきっているわけです。
なので、「Country Name」で再度アクションを起こしたいのであれば、
expect { ... }
を繰り返し記述するか、while などを上手く使うようにしなければ、
恐らく望みどおりの動作をしないと思います。
abi
会議室デビュー日: 2008/10/21
投稿数: 4
投稿日時: 2008-10-21 17:11
あるかな様

>「Country Name」で再度アクションを起こしたいのであれば、
>expect { ... }
>を繰り返し記述するか、while などを上手く使うようにしなければ・・・
ということは以下のようにするということでしょうか。
------------------------------------------------------------
・・・
expect {
"Enter pass phrase for server.key:" {interact}
}
expect {
"Country Name" {send "JP\r";exp_continue}
}
expect {
"State or Province" {send "Tokyo\r";exp_continue}
}
・・・
-------------------------------------------------------------
このようにexpectを繰り返し書いても、Country Nameの箇所でJPがsendされずに止まってしまいます。
whileはTCLの文法で書くんですよね。もう少し勉強してみます。

他にもご指摘あれば宜しくお願い致します。
あるかな
大ベテラン
会議室デビュー日: 2003/11/04
投稿数: 245
投稿日時: 2008-10-21 23:00
べた書きするのであれば、
コード:
expect "Enter pass phrase for server.key:"
interact
expect "Country Name"
send "JP\n"
expect "State or Province"
send "Tokyo\n"
...


とかこんな感じじゃないでしょうか?
また「Country Nameの箇所でJPがsendされずに止まってしまいます」は、「Country Name」を
検知してない(=条件マッチしてない)可能性なども考えられます。

とりあえず、判例のある telnet 通信系などのサンプルで挙動を確認してみてはどうでしょうか。
認証書の設定出来る環境が今、手元に無いので expect でどう書けば良いか答えられずにすみません。

あと下記のサイトなどには目を通されましたか?
http://kansai.anesth.or.jp/gijutu/expect/doc-expect.php
http://www.mekou.com/~tsuyoshi/writing/LINUXWORLD/200312.txt
あるかな
大ベテラン
会議室デビュー日: 2003/11/04
投稿数: 245
投稿日時: 2008-10-21 23:08
引用:

あるかなさんの書き込み (2008-10-21 23:00) より:
また「Country Nameの箇所でJPがsendされずに止まってしまいます」は、「Country Name」を
検知してない(=条件マッチしてない)可能性なども考えられます。



ここの部分のお話ですが、検証方法は interact と取り除いて全て自動入力方式に切り替え、最後までスクリプトが流れるか、を確認すれば少なくとも検知(expect 文)での待機状態で
問題有無は見えてくると思います。
流れなかったら検知されてない or send の仕方が悪い訳で、
流れたら interact との組み合わせ?になるのかと。
abi
会議室デビュー日: 2008/10/21
投稿数: 4
投稿日時: 2008-10-22 09:34
あるかな様

何度もお返事いただいて、ありがとうございます。

教えていただいた通り、全ての入力項目を決めておき、expectとsendで自動で入力させるように書いてみたところ、うまく流れてserver.csrが作成されました。

>べた書きするのであれば、
で教えていただいた書き方では、今までと変わらず、interact(手入力)からexpect(自動入力)に切り替わらず、CountryNameの箇所で止まってしまいました。

やはりexpectとinteractをスクリプトの途中で併用するためには、別の制御文(for,whileなど)が必要ですね。
しかし、そういったサンプルがネット上に全然ないので、TCLから勉強しなおします。

何度も教えていただいてありがとうございました。
また何か分かったらご教授いただけると幸いです。


あるかな様以外の皆様もお気づきの事ありましたら、宜しくお願い致します。

スキルアップ/キャリアアップ(JOB@IT)