総数:9 今日:1 昨日:0
Memorandums

もくじ

自動入力する方法

expect をインストールする。

~$ 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
"

expectコマンドの説明

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 としてチェックできる。 

spawnしたプロセスの終了ステータスを得る

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言語の文法を知らないとちょっと戸惑う。

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