複数ファイルに対して同じことをする場合、対象のファイルを配列で定義する方法があります。 複数サーバーに対して同じ処理をする場合、対象サーバーを配列で定義して以下の方法と組み合わせることで、処理を1つのスクリプトにして簡単に実行できるケースがあります。
配列の要素を直接指定
シェルの配列では、"("と")"の間に、要素を書きます。要素と要素の区切りは、スペース、タブ、改行になります。 改行の使い方によって、以下のように分類できます。 見やすくて使いやすいのは、要素1つごとに改行です。
- 1行にまとめて書く
- 要素1つごとに改行
- 1行に複数要素で複数行
1行にまとめて書く場合は、スペースやタブを区切り文字と使い、改行は使いません。
変数名=(要素1 要素2 ... 要素N)
要素1つごとに改行する場合は以下のようになります。スペースやタブを入れてインデントすることも可能です。
変数名=( 要素1 要素2 .... 要素N )
両方が混在して1行に複数要素で複数行とすることもできます。
変数名=( 要素1 要素2 要素3 要素4 要素5 要素6 .... 要素N )
例 3つのファイルの配列
# 1行にまとめた FIRST=(/var/log/messages /var/log/maillog /home/vagrant/.bash_history) # 要素1つごとに改行 SECOND=( /var/log/messages /var/log/maillog /home/vagrant/.bash_history )
#!/bin/bash FILES=( /var/log/messages /var/log/maillog /home/vagrant/.bash_history ) for FPATH in "${FILES[@]}" do SIZE=`ls -l $FPATH | awk '{print $5}'` echo "$SIZE $FPATH" done実行結果は以下のようになります。
932 /var/log/messages 0 /var/log/maillog 13975 /home/vagrant/.bash_history
-
インデント
配列の中では、スペースやタブは区切り文字とみなされますが、インデントとして見やすくすることも可能です。
例 タブでインデント
#!/bin/bash FILES=( /var/log/messages /var/log/maillog /home/vagrant/.bash_history ) for FPATH in "${FILES[@]}" do SIZE=`ls -l $FPATH | awk '{print $5}'` echo "$SIZE $FPATH" done実行結果はインデント無しと同じになります。タブをスペースに替えても同じになります。
932 /var/log/messages 0 /var/log/maillog 13975 /home/vagrant/.bash_history
要素の除外
要素1つごとに改行の場合、要素の前に"#"を入れると、"#"以降がコメントになり除外できます。
#!/bin/bash
FILES=(
/var/log/messages
# /var/log/maillog
/home/vagrant/.bash_history
)
for FPATH in "${FILES[@]}"
do
SIZE=`ls -l $FPATH | awk '{print $5}'`
echo "$SIZE $FPATH"
done
実行結果は以下のようになり、"#"を先頭に追加した2行目が除外されています。
932 /var/log/messages 13975 /home/vagrant/.bash_history
配列を1行で書いた場合、"#"を挿入すると、"#"から行の終わりまでコメントになります。 除外したくない要素があると順番を入れ替える必要があったりするので、要素ごとに改行した方が便利です。
要素にスペースやタブがある
要素にスペースやタブが含まれる場合、ダブルクォートかシングルクォートで囲みます。
#!/bin/bash FILES=( /var/log/messages /var/log/maillog "/home/vagrant/test space tab.txt" ) for FPATH in "${FILES[@]}" do echo "$FPATH" done実行結果は以下のようになります。
/var/log/messages /var/log/maillog /home/vagrant/test space tab.txt
要素に改行がある
改行が含まれる場合、ダブルクォートで囲むことで1つの要素になりますが、改行はスペースに替わりますので注意してください。
別ファイルで配列の要素を定義
複数のスクリプトで同じ配列を使用する場合、配列の要素の定義だけをファイルにすることができます。 この場合、定義ファイルは以下の2つのどちらかで作成します。
- スクリプトファイル
- テキストファイル
-
スクリプトファイル
配列の要素の定義だけをスクリプトファイルとすると、以下のようになります。
#!/bin/bash HOSTS=( one.example.com two.example.com three.example.com )これを利用するスクリプトは、ドットのあとにスペースを1つ挟んでファイルのパスを書きます。 ドットは、指定ファイルをスクリプトファイルとして読み込み実行します。
. [ファイルのパス]
#!/bin/bash . hosts.sh for host in "${HOSTS[@]}" do echo $host doneこの実行結果は以下になります。
one.example.com two.example.com three.example.comhosts.shが同じディレクトリに無く、そのパスが/home/vagrant/host.shの場合、以下のように読み込むファイルのパスを指定します。
. /home/vagrant/hosts.sh
スクリプトの配列の中では、空白や"#"から始まるコメントを書くことが可能なので、以下のように1定義ごとに空白行、コメントやインデントを入れて見やすくすることが可能です。
#!/bin/bash HOSTS=( one.example.com # test 2 two.example.com # test3 three.example.com )
テキストファイル
テキストファイルで要素を定義する場合、改行やスペース、タブが要素の区切りになります。
one.example.com two.example.com three.example.comこれを利用する場合、以下のようになります。
#!/bin/bash HOSTS=(`cat hosts.txt`) for host in "${HOSTS[@]}" do echo $host done実行結果は以下のようになります。
one.example.com two.example.com three.example.com注意 テキストファイルの場合、改行だけの行も要素となるので、要素間に空白行を入れないようにします。 また、"#"からの行も要素となります。
例 host.txtが以下のように要素間に空白などがある場合
one.example.com # test 2 two.example.com # test3 three.example.comこのファイルだと以下のようになります。
one.example.com # test 2 two.example.com # test3 three.example.com