zshとbashの違い

zshはbashとは少し違う

このことを気づいたきっかけは、自分が転職を機にMacを使うようになって、せっかくの機会なのでzshを使っていたところ、bashで正常に動作していたコマンドがエラーになったことでした。

bashはデフォルトで.items[]をリテラルな文字列として扱います。

1
2
3
# bash
echo '{"items": ["a", "b", "c"]}' | jq -r .items[] | xargs echo
a b c

zshはデフォルトで、クォートされていない引数をグロブパターンとして扱おうとします。

1
2
3
# zsh
echo '{"items": ["a", "b", "c"]}' | jq -r .items[] | xargs echo
zsh: no matches found: .items[]

zshでこのコマンドを正しく動作させるには、.items[]をクォートで囲む必要があります。

1
2
echo '{"items": ["a", "b", "c"]}' | jq -r '.items[]' | xargs echo
a b c

shellcheckを使おう

こんな感じで、zshはbashと挙動が違うことがあるので、気をつけないといけません。
引数の評価の違いや単語分割の違いがあり、シェルスクリプトのバグの原因になることがあるので、shellcheckを使って、シェルスクリプトのお作法をチェックすることが大切だと改めて感じました。

Macならインストールは以下のコマンド

1
brew install shellcheck

単にzshはbashの上位互換だろうくらいに思っていたので、こういった挙動の違いがあることにびっくりしました。
既存スクリプトの移行や流用などが必要な場合には、念の為にshellcheckを使っていこうと思った出来事でした。