1. 配列の要素を直接指定
  2. 別ファイルで配列の要素を定義

複数ファイルに対して同じことをする場合、対象のファイルを配列で定義する方法があります。 複数サーバーに対して同じ処理をする場合、対象サーバーを配列で定義して以下の方法と組み合わせることで、処理を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つ挟んでファイルのパスを書きます。 ドットは、指定ファイルをスクリプトファイルとして読み込み実行します。
    . [ファイルのパス]

    例 ホスト名の定義ファイルがhosts.shで、同じディレクトリにある場合
    #!/bin/bash
    
    . hosts.sh
    
    for host in "${HOSTS[@]}"
    do
        echo $host
    done
    この実行結果は以下になります。
    one.example.com
    two.example.com
    three.example.com
    hosts.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