総数:9 今日:1 昨日:0
Memorandums
~$ 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) のトリガを処理しています ...
$ 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
$ 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
"
https://kazmax.zpp.jp/cmd/e/expect.1.html
wait コマンド
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 としてチェックできる。
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言語の文法を知らないとちょっと戸惑う。