2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

プログラムとの対話を自動化する expect の簡単なプログラム例

Posted at

やりたいこと

会社で自動化したい処理がいくつかあり、その中に対話形式のプログラムがあるため expect を利用することに。
初めて expect を使うため、下記の記事を参考にして簡単なプログラムを作ってみましたのでメモ。

「とりあえず動かしてみたい!」という方には参考になるかもしれません。

参考記事

Linuxの対話がめんどくさい?そんな時こそ自動化だ!-expect編-

インストール

以下の方法で expect コマンドをインストールします。
ちなみに OS は CentOS 7.6 で実行しています。

$ sudo yum install expect

簡単な対話プログラムを自作

expect のテストとして使えそうな簡単な対話プログラムがなかったので自作しました(シェルのお勉強を兼ねて)。

self-introduction.sh

# !/bin/bash

GetInfo() {
        item=$1
        read -p "${item}: " val
        echo ${val} # 受け取った値を標準出力することで値を渡す
}

SelfIntroduction() {
        name=`GetInfo name` # 関数の結果を変数に代入する場合、関数名をバッククオートで囲む
        age=`GetInfo age`
        echo "Hello! I'm ${name}, ${age} years old."
}

SelfIntroduction

実行すると対話形式で nameage を聞かれ、入力が終わると Hello! I'm [名前], [年齢] years old. と出力されるだけの簡単なプログラムです。

実行した結果

$ sh self-introduction.sh
name: Katsuo
age: 11
Hello! I'm Katsuo, 11 years old.

expect を使ってみる

上記のプログラムを対話せずに実行するため expect を使ってみます。

名前と年齢の値は引数として渡します。

expect には書き方が2パターンあるようで、1つはコマンドとして書く方法、もう1つはプログラム言語っぽく書く方法です。

両方のパターンを試してみましたが、可読性などを考えると後者がおすすめです(ネットを調べるとなぜか前者で書かれていることが多い)。

今回は後者のプログラム言語っぽく書く方法でやってみます。

プログラム言語っぽく書いてみる

以下が完成版です。
これでプログラムと対話することなく、名前と年齢を引数として渡すことで実行することができます。

self-introduction.exp
# !/usr/bin/expect

set name [lindex $argv 0]
set age  [lindex $argv 1]

spawn ./self-introduction.sh

expect {
        "name" {
                send "${name}\n"
                exp_continue
        }
        "age" {
                send "${age}\n"
                exp_continue
        }
        "\\\$" {
                exit 0
        }
}

exit 0

実行してみる

以下の1行目を実行するだけで、止まることなく最後まで処理が実行されます。

$ expect self-introduction.exp Katsuo 11
name: Katsuo
age: 11
Hello! I'm Katsuo, 11 years old.

簡単に解説

# !/usr/bin/expect

いわゆるシバンです。
「これから expect でプログラム書きますよ!」というお知らせです。

set name [lindex $argv 0]
set age  [lindex $argv 1]

引数として受け取った値を変数に入れてます。

spawn ./self-introduction.sh

spawn で指定した対話プログラムが自動化の対象となります。
今回は同じディレクトリ内にある self-introduction.sh を対象としています。

expect {
    ...処理...
}

expect { } の中に自動化するための具体的な処理を書いていきます。

"name" {
        send "${name}\n"
        exp_continue
}
"age" {
        send "${age}\n"
        exp_continue
}
"\\\$" {
        exit 0
}

name でパターンマッチしたら、変数 ${name} を入力してリターンします。
同様に、age でパターンマッチしたら、変数 ${age} を入力してリターンします。

exp_continue を入力しておくことで expect { } ブロックから抜け出さずに処理を続けることができます。

\\\$ の部分は、プロンプトの入力待ち状態になったら expect { } ブロックから抜け出すための処理です。
プロンプトは環境によって異なるため、#% などに編集が必要な場合があります。
(コマンドプロンプトを起動して、入力待ちのときに表示される記号のことです。)

また、詳しい理由は分かりませんが \ 3つ必要です。
内部でどのような処理が行われているか不明ですが、エスケープが2回必要みたいです。

以上!

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?