シェルスクリプトで配列変数を参照する際は “${変数名}” と記述する癖をつけたほうが良い
はじめに
チームメンバがシェルスクリプトを書いていました。
変数を参照する際のちょっとした不備ではまりました。
変数をダブルクォートで囲んでいなかったことが原因だったのですが、どんなケースだったかを紹介します。
検証環境
$ uname -moi
x86_64 x86_64 GNU/Linux
$ bash -version | head -n 1
GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu)
配列変数を利用してループ処理を行うケースで問題が発生
問題が発生していたのは配列変数を受け取り、ループ処理するロジックでした。
ここでは test.sh というファイル名で保存されていたとしましょう。
#!/usr/bin/env bash
LIST=(
"111"
"22 22 22"
"333"
)
for TXT in ${LIST[@]}; do
# ***実際にはこの部分にロジックが記述されていました***
echo "${TXT}"
done
想定では、このループ処理は 3 行の文字列を出力する想定でした。
111
22 22 22
333
ところが実行結果は以下のようになりました。
$ ./test.sh
111
22
22
22
333
これは LIST
という配列変数の参照の仕方に問題があったためです。
正しく "${LIST[@]}"
で参照する
先の test.sh スクリプトは以下のように修正すれば想定通りの挙動をします。
#!/usr/bin/env bash
LIST=(
"111"
"22 22 22"
"333"
)
# **先ほどとの違いはここ!ダブルクォートで囲んでいます。**
for TXT in "${LIST[@]}"; do
echo "${TXT}"
done
実行結果は以下のようになります。
$ ./test.sh
111
22 22 22
333
このように、配列の各要素を参照する際には、 "${LIST[@]}" のように、ダブルクォートで囲んでやらなければスペースを含む値の場合に想定通りのループ処理をしてくれません。
変数を参照する際には "${VAR}" / "${VAR[@]}" と記述する癖をつけよう
変数を参照する際には、 "${VAR}" / "${VAR[@]}" と記述する癖をつけたほうが良いです。
こんなゆるい言語を使わなければ良い、というのも一つですが、Docker や Kubernetes が導入されるケースが多い昨今、Bash や Posix 準拠のシェルが活躍する場も多いです。
この点を心がけるだけで随分バグが減るはずです。
shellcheckを導入しリアルタイムでコードチェックを行う
shellcheck という、シェルスクリプトの構文チェックツール( Java の checkstyle や PHP の PHP-CS-Fixer 、 JavaScript の ESLint )を導入するのがおすすめです。
僕は Neovim を使っていますが、プラグインで容易に導入できます。
コードを書いている時にリアルタイムでエラーを表示してくれます。
ひとこと
Neovim のコードスニペットツールが大活躍しています。
VSCode や Eclipse のようなツール、IntelliJ にもスニペット登録機能があるため、活用すると "${VAR}" の記述も面倒ではならなくなります。
ディスカッション
コメント一覧
まだ、コメントがありません