#author("2019-03-06T17:00:18+09:00","","")
#author("2019-03-06T17:04:40+09:00","","")
#nofollow
#norelated
総数:&counter(total); 今日:&counter(today); 昨日:&counter(yesterday);&br;
[[Memorandums]]

* もくじ [#m07dd3f9]

#contents

* 自動入力する方法 [#c7a10b82]
**expect をインストールする。 [#b4a0537c]
 ~$ sudo apt-get -y install expect

 パッケージリストを読み込んでいます... 完了
 依存関係ツリーを作成しています                
 状態情報を読み取っています... 完了
 以下の追加パッケージがインストールされます:
   tcl-expect
 以下のパッケージが新たにインストールされます:
   expect tcl-expect
 アップグレード: 0 個、新規インストール: 2 個、削除: 0 個、保留: 327 個。
 241 kB のアーカイブを取得する必要があります。
 この操作後に追加で 538 kB のディスク容量が消費されます。
 取得:1 http://jp.archive.ubuntu.com/ubuntu xenial/universe amd64 tcl-expect amd64 5.45-7 [104 kB]
 取得:2 http://jp.archive.ubuntu.com/ubuntu xenial/universe amd64 expect amd64 5.45-7 [137 kB]
 241 kB を 0秒 で取得しました (416 kB/s)
 以前に未選択のパッケージ tcl-expect:amd64 を選択しています。
 (データベースを読み込んでいます ... 現在 421779 個のファイルとディレクトリがインストールされています。)
 .../tcl-expect_5.45-7_amd64.deb を展開する準備をしています ...
 tcl-expect:amd64 (5.45-7) を展開しています...
 以前に未選択のパッケージ expect を選択しています。
 .../expect_5.45-7_amd64.deb を展開する準備をしています ...
 expect (5.45-7) を展開しています...
 libc-bin (2.23-0ubuntu10) のトリガを処理しています ...
 man-db (2.7.5-1) のトリガを処理しています ...
 tcl-expect:amd64 (5.45-7) を設定しています ...
 expect (5.45-7) を設定しています ...
 libc-bin (2.23-0ubuntu10) のトリガを処理しています ...
 

**パスワードを要求する処理の例 [#mfca1aea]

 $ cat request_for_password.sh 
 #!/bin/bash
 declare -i DELAY_TIME=3
 PASSWORD_0="ABC"
 PASSWORD_1="XYZ"
 
 sleep ${DELAY_TIME}
 
 echo "enter password 0 >"
 read input_characters
 if [ ${input_characters} != "${PASSWORD_0}" ] ; then
 	echo "password 0 is denied."
 	exit 1
 fi
 echo "password 0 is successfully accepted."
 
 sleep ${DELAY_TIME}
 
 echo "enter password 1 >"
 read input_characters
 if [ ${input_characters} != "${PASSWORD_1}" ] ; then
 	echo "password 1 is denied."
 	exit 2
 fi
 echo "password 1 is successfully accepted."
 
 sleep ${DELAY_TIME}
 
 exit 0

**パスワードを自動で応答する処理 [#k3439231]

 $ cat reply_to_passwords.sh 
 #!/bin/bash
 
 PASSWORD_0="ABC"
 PASSWORD_1="XYZ"
 
 expect -c "
 set timeout -1
 spawn env ./request_for_password.sh
 expect {
 	\"enter password 0 >\" {
 		send \"${PASSWORD_0}\n\"
 		exp_continue
 	}
 	\"enter password 1 >\" {
 		send \"${PASSWORD_1}\n\"
 		exp_continue
 	}
 }
 exit 0
 "

**expectコマンドの説明 [#hdc50373]
https://kazmax.zpp.jp/cmd/e/expect.1.html &br;
wait コマンド&br;

 wait [args]
 は、spawn されたプロセス(あるいは、名前つきのプロセスがなければ現在のプロセス) が終了するのを待つ。
 wait は、通常 4 つの整数のリストを帰す。
 最初の整数は、終了を待ち構えているプロセスの pid である。
 2 つめの整数は、関連する spawn id である。
 3 つめの整数は、オペレーティングシステムエラーがあれば -1、 そうでなければ、0 である。
 3 つめの整数が 0 であれば、4 つめの整数はspawnされたプロセスからのリターン コードである。
 3 つめの整数が -1 であれば、4 つめの整数はオペレーティングシステム によって設定された errno の値である。グローバル変数 errorCode も設定される。
 追加の要素が wait の復帰値に加わっても構わない。
 オプションの5つめの要素は、情報クラスの 識別子である。
 今のところ、この要素の唯一可能な値は CHILDKILLED で、
 その場合、次の二つの値が C スタイルのシグナル名と短い文書による記述である。 
 -i フラグによって、wait を行なう名前付き spawn_id(プロセス ID ではなく)を 指定する。
 SIGCHLD ハンドラの内部では、spawn ID -1 を指定することで、 spawn されたプロセスのいずれかを wait できる。 
 -nowait フラグを指定すると、wait が成功の復帰値で即時復帰する。
 (あとで)そのプロセスが exit すると、自動的に後始末が行なわれ、明示的に wait する必要がない。 
 wait コマンドは、引数に "-i -1" を指定することによって、
 fork したプロセスを待つためにも使われる。
 spawn したプロセスに用いられる場合と異なり、このコマンドはいつでも実行できる。
 どのプロセスを待つかを制御することは出来ないが、返り値はプロセス ID としてチェックできる。 


**spawnしたプロセスの終了ステータスを得る [#a37c4e37]
http://root-mode2.blogspot.com/2010/10/expect-spawn.html

 spawnしたプロセスの終了ステータスを得たいことがある。
 この場合はwaitでプロセスの終了を待つと、結果が返ってくる。
 結果はリストになっていて3番目(インデックス2)が-1の場合は
 OSエラー、0の場合は4番目(インデックス3)にswawnしたプロセスの
 終了ステータスが入っている。
 
 スクリプトの例。読み取り権のないファイルをcatして終了ステータスを得る。
 spawn cat /etc/shadow
 expect eof
 catch wait result
 set OS_ERROR [ lindex $result 2 ]
 if { $OS_ERROR == -1 } {
         puts "Fail to exec"
         exit 127
 }
 set STATUS [ lindex $result 3 ]
 exit $STATUS
 スクリプト自体をcatの終了ステータスで終了する。
 
 
 実行結果
 $ expect test.expect
 spawn cat /etc/shadow
 cat: /etc/shadow: Permission denied
 $ echo $?
 1
 きちんと1が返っている。
 
 expectはTcl言語の文法を知らないとちょっと戸惑う。

**パスワードを自動で応答する処理その2 spawnしたプロセスの終了ステータスを得る [#w084e842]

 $ cat reply_to_passwords.sh 
 #!/bin/bash
 
 PASSWORD_0="ABC"
 PASSWORD_1="XYZ"
 
 expect -c "
 set timeout -1
 spawn env ./request_for_password.sh
 expect {
 	\"enter password 0 >\" {
 		send \"${PASSWORD_0}\n\"
 		exp_continue
 	}
 	\"enter password 1 >\" {
 		send \"${PASSWORD_1}\n\"
 		exp_continue
 	}
 }
 catch wait result_of_spawned_process
 set OS_ERROR [ lindex \$result_of_spawned_process 2 ]
 if { \$OS_ERROR == -1 } {
         puts \"Fail to exec\"
         exit 127
 }
 set STATUS [ lindex \$result_of_spawned_process 3 ]
 exit \$STATUS
 "
 echo $?
 rval=$?
 echo "${rval}"
 if [ ${rval} -ne 0 ] ; then
         echo "error occurred"
 fi
 echo "done successfully."


トップ   差分 バックアップ リロード   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS