https://qiita.com/yabeenico/items/72b904d4bb0b6d732a86#配列の利点-arrays-pros
flags
flags+
mybinary
flags+
mybinary
/directory
# get_arguments は全てを STDOUT に書き出すが、
# 引数のリストとなる前に先と同様の展開処理が走る。
mybinary $(get_arguments)
配列の利用によりスクリプトの複雑さが増大するリスクがある。
配列はリストを安全に作成したり渡したりする場合に利用されるべきである。特に、コマンド引数のセットを構築する時、クオートが錯乱する問題を避ける場合に利用せよ。配列にアクセスするときはクオート展開 - "${array[@]}"
- を利用せよ。しかしながら、もしさらに高度なデータ操作が要求される場合は、そもそもシェルスクリプトの利用は避けるべきである。上記を見よ。
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
の方が大抵安全であり明瞭である。
let
や $[ ... ]
や expr
ではなく、常に (( ... ))
や $(( ... ))
を利用せよ。