https://qiita.com/yabeenico/items/72b904d4bb0b6d732a86#配列の利点-arrays-pros

Shell Style Guide

Section Contents
背景 (Background) どのシェルを使うか (Which Shell to Use) - いつシェルを使うか (When to use Shell)
シェルファイルとインタープリタ呼出 (Shell Files and Interpreter Invocation) ファイル拡張子 (File Extensions) - SUID/SGID
環境 (Environment) STDOUT vs STDERR
コメント (Comments) File Header - 関数コメント (Function Comments) - コメントの実装 (Implementation Comments) - TODO コメント (TODO Comments)
フォーマット (Formatting) インデント (Indentation) - 行の長さと長い文字列 (Line Length and Long Strings) - パイプライン (Pipelines) - ループ (Loops) - case 文 (Case statement) - 変数展開 (Variable expansion) - クオート (Quoting)
機能とバグ (Features and Bugs) ShellCheck - コマンド置換 (Command Substitution) - Test - 文字列の test (Testing Strings) - ファイル名のワイルドカード展開 (Wildcard Expansion of Filenames) - Eval - 配列 (Arrays) - 配列の利点 (Arrays Pros) - 配列の欠点 (Arrays Cons) - いつ配列を使うか (Arrays Decision) - while へのパイプ (Pipes to While) - 算術演算 (Arithmetic)
命名規則 (Naming Conventions) 関数名 (Function Names) - 変数名 (Variable Names)
定数と環境変数 (Constants and Environment Variable Names) 読み取り専用変数 (Read-only Variables) - 局所変数を利用せよ (Use Local Variables) - 関数の位置 (Function Location) - main
コマンド呼び出し (Calling Commands) 返り値判定 (Checking Return Values) - ビルトインコマンド vs 外部コマンド (Builtin Commands vs. External Commands)
結論 (Conclusion)

  flags

flags+
mybinary

flags+
mybinary

   /directory

# get_arguments は全てを STDOUT に書き出すが、
# 引数のリストとなる前に先と同様の展開処理が走る。
mybinary $(get_arguments)

配列の利点 (Arrays Pros)

配列の欠点 (Arrays Cons)

配列の利用によりスクリプトの複雑さが増大するリスクがある。

いつ配列を使うか (Arrays Decision)

配列はリストを安全に作成したり渡したりする場合に利用されるべきである。特に、コマンド引数のセットを構築する時、クオートが錯乱する問題を避ける場合に利用せよ。配列にアクセスするときはクオート展開 - "${array[@]}" - を利用せよ。しかしながら、もしさらに高度なデータ操作が要求される場合は、そもそもシェルスクリプトの利用は避けるべきである。上記を見よ。

while へのパイプ (Pipes to While)

while へパイプする場合はプロセス置換か readarray ビルトイン (bash4+) を優先的に利用せよ。パイプはサブシェルを作るため、パイプライン中における変数の変更は親シェルに伝播しない。while へ至るパイプで発生する暗黙的なサブシェルは、追いかけるのが困難な分かりにくいバグを誘引する。

last_line='NULL'
your_command | while read -r line; do
  if [[ -n "${line}" ]]; then
    last_line="${line}"
  fi
done

# これは常に 'NULL' を出力する!
echo "${last_line}"

プロセス置換もサブシェルを作成する。しかしながら、while (やその他のコマンド) をサブシェル内に置くことなく、サブシェルから while へのリダイレクトを可能にする。

last_line='NULL'
while read line; do
  if [[ -n "${line}" ]]; then
    last_line="${line}"
  fi
done < <(your_command)

# これは your_command の出力の最後の空行でない行を出力する
echo "${last_line}"

Note: 出力を for ループでイテレートする際は注意せよ。for var in $(...) では、出力は行ではなくスペースで分割される。出力が想定外のスペースを含むことがないことが分かっているためにこれが安全であるといえる場合があるが、それが明確でなかったり可読性を改善しない場合は ($(...) 内のコマンドが長い場合など)、while read ループか readarray の方が大抵安全であり明瞭である。

算術演算 (Arithmetic)

let$[ ... ]expr ではなく、常に (( ... ))$(( ... )) を利用せよ。