「シェルスクリプトの基礎 - 入出力」の版間の差分
126行目: | 126行目: | ||
|} | |} | ||
</center> | </center> | ||
<br><br> | |||
== expectコマンド == | |||
expectコマンドを使用すると、任意のコマンドの出力を待ち受けて、自動でそれに対する入力を行うことができる。<br> | |||
例えば、SSHやRsyncのパスワード入力を自動化することができる。<br> | |||
<br> | |||
expectコマンドがインストールされていない場合は、パッケージ管理システム等を使用してインストールする。<br> | |||
<br> | |||
==== expectコマンドの基本 ==== | |||
以下の例では、簡単なユーザ入力を必要とするスクリプトを自動で動作させている。<br> | |||
<syntaxhighlight lang="sh"> | |||
#!/bin/sh | |||
read -p "Enter your name: " NAME | |||
echo "Hello, $NAME" | |||
</syntaxhighlight> | |||
<br> | |||
これを実行すると、以下のようにユーザ入力の待ち受け状態となる。<br> | |||
Enter your name: | |||
<br> | |||
この状態において、自動的に入力を行うには、以下のように<code>expect -c</code>コマンドを使用する。<br> | |||
以下の例では、外部のシェルスクリプト(Sample.sh)の入力待ちに対して、自動的にMakuという入力を行っている。<br> | |||
<syntaxhighlight lang="python"> | |||
#!/bin/sh | |||
expect -c " | |||
set timeout 3 | |||
spawn ./Sample.sh | |||
expect \"Enter your name:\" | |||
send \"Maku\n\" | |||
interact | |||
" | |||
# 出力 | |||
spawn ./Sample.sh | |||
Enter your name: Maku | |||
Hello, Maku | |||
</syntaxhighlight> | |||
<br> | |||
<code>expect -c</code>コマンドのダブルクォーテーションで囲まれた部分には、実行するシェルスクリプトを記述する。<br> | |||
また、この内部でダブルクォーテーションを使用する場合は、<code>\"</code>と記述してエスケープしなければいけないことに注意する。<br> | |||
<br> | |||
expect -cコマンドの内部の各行は、以下のような意味を持っている。<br> | |||
* set timeout 3 | |||
*: 外部のシェルスクリプト(Sample.sh)の実行を3秒待つ。 | |||
* spawn ./Sample.sh | |||
*: 指定した外部プログラム(./greet.sh)を実行する。 | |||
* expect \"Enter your name:\" | |||
*: 外部プログラムの出力(Enter your name:)を待つ。 | |||
* send \"Maku\n\" | |||
*: 外部プログラムにMakuと入力して、最後にEnterを入力する。 | |||
* interact | |||
*: 外部プログラムとのインタラクションへ戻る。 | |||
<br> | |||
==== SSH接続やRsync接続のパスワード入力を自動化する ==== | |||
SSHコマンドやRsyncコマンド等のパスワード入力も自動化することができる。<br> | |||
ただし、シェルスクリプト等にパスワードを平文で記述することになるので、ファイルの扱いには十分に注意すること。<br> | |||
<br> | |||
以下の例では、SSHコマンドがパスワード入力を求めてきた時、自動でパスワードを入力してログインしている。<br> | |||
<syntaxhighlight lang="sh"> | |||
#!/bin/sh | |||
expect -c " | |||
set timeout 3 | |||
spawn ssh <ユーザ名>@<ドメイン名またはIPアドレス> | |||
expect \"password:\" | |||
send \"<パスワード>\n\" | |||
interact | |||
" | |||
# 出力 | |||
spawn ssh <ユーザ名>@<ドメイン名またはIPアドレス> | |||
<ユーザ名>@<ドメイン名またはIPアドレス>'s password: | |||
Last login: Sat Nov 10 19:58:51 2018 from hogehoge.ap.example.jp | |||
</syntaxhighlight> | |||
<br> | |||
ログイン後に、何らかのコマンド(例 : ls -alF)を実行するところまで自動化するのであれば、<br> | |||
以下のように、プロンプトの$を待ち受けて、次の入力を行えばよい。<br> | |||
<syntaxhighlight lang="sh"> | |||
#!/bin/sh | |||
expect -c " | |||
set timeout 3 | |||
spawn ssh <ユーザ名>@<ドメイン名またはIPアドレス> | |||
expect \"password:\" | |||
send \"<パスワード>\n\" | |||
expect \"$\" | |||
send \"ls -aFl\n\" | |||
interact | |||
" | |||
</syntaxhighlight> | |||
<br> | |||
また、Rsyncコマンドでファイル転送する場合も、同様にパスワード入力を自動化できる。<br> | |||
<syntaxhighlight lang="sh"> | |||
#!/bin/sh | |||
expect -c " | |||
spawn rsync -r -h -v --delete public <ユーザ名>@<ドメイン名またはIPアドレス>:public | |||
expect \"Password:\" | |||
send \"<パスワード>\n\" | |||
interact | |||
" | |||
</syntaxhighlight> | |||
<br><br> | <br><br> | ||
2020年11月30日 (月) 02:21時点における版
概要
ここでは、シェルスクリプトでキーボードからの入力を受け付ける方法を記載する。
入力
readコマンドを使用することで、キーボードから入力した内容を変数に格納することができる。
read 変数名
入力データの表示
以下の例では、キーボードで入力したデータを変数DATA
へ格納し、その内容を表示させている。
read
コマンドで入力データを読み込んだ後は、そのまま処理が継続する。
これを利用することで、何かキー入力されるまで処理を停止させることができる。
#!/bin/bash
echo -n "Press any key: "
read DATA
echo ""
echo "Entered key: $DATA"
-pオプションを使用することで、こういう記述方法ができる。
read -p "表示する文" 変数名
#!/bin/bash
read -p "Press any key: " DATA
echo ""
echo "Entered key: $DATA"
入力データと処理の分岐
caseコマンドと組み合わせることで、入力されたキーの内容によって処理を分岐することができる。
以下では、yキーを入力した場合はOK、nキーを入力した場合はNG、それ以外の場合はPush y or n key.と表示させる。
#!/bin/bash
read -p "Are you ok ? (y/n): " DATA
case "$DATA" in
[yY]) echo "OK" ;;
[nN]) echo "NG" ;;
*) echo "Push y or n key."
esac
入力データと反復処理
入力した内容によって処理を繰り返したい場合は、whileコマンドと組み合わせる。
以下のシェルスクリプトでは、
Repeat ?(y/n):と表示した後、yキーを入力すると処理を繰り返して、また、Repeat ?(y/n):と表示して入力待ちとなる。
nキーを入力すると、End Repead.と表示してbreakにより繰り返し処理から抜ける。
yキーまたはnキー以外が入力された場合、Input y or n keyと表示して、再度、Repeat ?(y/n):と表示して入力待ちとなる。
#!/bin/bash
while :
do
read -p "Repeat ? (y/n): " DATA
if [ "$DATA" = "y" ]; then
echo "Repeat !!"
elif [ "$DATA" = "n" ]; then
echo "End repead."
break
else
echo "Input y or n key"
fi
done
複数の入力データ
変数を複数用意することで複数の入力を受け付けることができる。
以下のシェルスクリプトでは、変数DATA1、DATA2、DATA3という3つの変数を宣言しているので、
スペース(タブでも可)で区切った3つの値を変数に格納することができる。
#!/bin/bash
read -p "Press any key: " DATA1 DATA2 DATA3
echo ""
echo "Entered key: $DATA1"
echo "Entered key: $DATA2"
echo "Entered key: $DATA3"
※区切り文字を変更する場合
区切り文字は、環境変数のIFSを使用することで変更することができる。
以下のシェルスクリプトでは、区切り文字をカンマ(,)に変更して実行している。
#!/bin/bash
IFS=, read -p "Press any key: " DATA1,DATA2,DATA3
echo ""
echo "Entered key: $DATA1"
echo "Entered key: $DATA2"
echo "Entered key: $DATA3"
readコマンドのオプション
readコマンドには複数のオプションがあるが、下表によく使用するオプションを記載する。
オプション | 説明 |
---|---|
-a 変数 | 入力した値を配列変数に格納する。 |
-n 文字数 | 文字数で指定した分だけ読み込む。 キーボードで直接入力すると、2文字を入力した時点で、自動的に入力処理が終了して値が変数に格納される。 また、コピー&ペーストで2文字以上の文字を入力した場合も、指定した分だけが変数に格納される。 |
-p 文字列 | 文字列を表示した後、入力待ちになる。 改行文字が入力されると、入力の受け付けが終了する。 |
-r | \(バックスラッシュ)を文字列として変数に格納する。 |
-s | 画面上に入力した文字を表示しない。 |
-t 秒数 | 入力待ち時間に制限を付ける。 |
expectコマンド
expectコマンドを使用すると、任意のコマンドの出力を待ち受けて、自動でそれに対する入力を行うことができる。
例えば、SSHやRsyncのパスワード入力を自動化することができる。
expectコマンドがインストールされていない場合は、パッケージ管理システム等を使用してインストールする。
expectコマンドの基本
以下の例では、簡単なユーザ入力を必要とするスクリプトを自動で動作させている。
#!/bin/sh
read -p "Enter your name: " NAME
echo "Hello, $NAME"
これを実行すると、以下のようにユーザ入力の待ち受け状態となる。
Enter your name:
この状態において、自動的に入力を行うには、以下のようにexpect -c
コマンドを使用する。
以下の例では、外部のシェルスクリプト(Sample.sh)の入力待ちに対して、自動的にMakuという入力を行っている。
#!/bin/sh
expect -c "
set timeout 3
spawn ./Sample.sh
expect \"Enter your name:\"
send \"Maku\n\"
interact
"
# 出力
spawn ./Sample.sh
Enter your name: Maku
Hello, Maku
expect -c
コマンドのダブルクォーテーションで囲まれた部分には、実行するシェルスクリプトを記述する。
また、この内部でダブルクォーテーションを使用する場合は、\"
と記述してエスケープしなければいけないことに注意する。
expect -cコマンドの内部の各行は、以下のような意味を持っている。
- set timeout 3
- 外部のシェルスクリプト(Sample.sh)の実行を3秒待つ。
- spawn ./Sample.sh
- 指定した外部プログラム(./greet.sh)を実行する。
- expect \"Enter your name:\"
- 外部プログラムの出力(Enter your name:)を待つ。
- send \"Maku\n\"
- 外部プログラムにMakuと入力して、最後にEnterを入力する。
- interact
- 外部プログラムとのインタラクションへ戻る。
SSH接続やRsync接続のパスワード入力を自動化する
SSHコマンドやRsyncコマンド等のパスワード入力も自動化することができる。
ただし、シェルスクリプト等にパスワードを平文で記述することになるので、ファイルの扱いには十分に注意すること。
以下の例では、SSHコマンドがパスワード入力を求めてきた時、自動でパスワードを入力してログインしている。
#!/bin/sh
expect -c "
set timeout 3
spawn ssh <ユーザ名>@<ドメイン名またはIPアドレス>
expect \"password:\"
send \"<パスワード>\n\"
interact
"
# 出力
spawn ssh <ユーザ名>@<ドメイン名またはIPアドレス>
<ユーザ名>@<ドメイン名またはIPアドレス>'s password:
Last login: Sat Nov 10 19:58:51 2018 from hogehoge.ap.example.jp
ログイン後に、何らかのコマンド(例 : ls -alF)を実行するところまで自動化するのであれば、
以下のように、プロンプトの$を待ち受けて、次の入力を行えばよい。
#!/bin/sh
expect -c "
set timeout 3
spawn ssh <ユーザ名>@<ドメイン名またはIPアドレス>
expect \"password:\"
send \"<パスワード>\n\"
expect \"$\"
send \"ls -aFl\n\"
interact
"
また、Rsyncコマンドでファイル転送する場合も、同様にパスワード入力を自動化できる。
#!/bin/sh
expect -c "
spawn rsync -r -h -v --delete public <ユーザ名>@<ドメイン名またはIPアドレス>:public
expect \"Password:\"
send \"<パスワード>\n\"
interact
"
出力
echoコマンド
echoコマンドで変数の値を出力する時は、以下のように、ダブルクォートで囲む必要がある。
これは、変数展開が行われることによりダブルクォートが取り除かれ、echoコマンドに3つのパラメータが渡されたものとして扱われる。
パラメータの区切りとして使用するスペースの数は関係なく、各パラメータ(AAA、BBB、CCC)が1つのスペースで結合されて出力される。
# 実行
$DATA="AAA BBB CCC"
echo "$DATA"
# 出力
AAA BBB CCC
echoコマンドと文字の色
echo
コマンドにおいて、出力内容の色を変更するには、以下のように記述する。
# 実行
error()
{
echo -e "\033[31m$*\033[00m"
}
warn()
{
echo -e "\033[33m$*\033[00m"
}
info()
{
echo -e "\033[32m$*\033[00m"
}
# 出力 error 'Error message' warn 'Warning message' info 'Information message'