#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."