rake タスク実行時の「zsh: no matches found」エラーの解決

macOS ではデフォルトのシェルとして zsh が採用されているため、この問題は頻繁に発生します。

zsh での例:

% bin/rake plugin:spec[discourse-solved]
zsh: no matches found: plugin:spec[discourse-solved]
なぜこのようなことが起こるのか?

これは、角括弧が glob パターンとして解釈されるためです。bash では glob がパターンに一致しなくてもコマンドは実行され、問題なく動作します。一方、zsh ではエラーを発生させ、rake を実行しません。

例を挙げると、bash では:

○ → echo bin/rake plugin:spec[discourse-solved]
bin/rake plugin:spec[discourse-solved]

○ → touch plugin:specd

○ → echo bin/rake plugin:spec[discourse-solved]
bin/rake plugin:specd

failglob オプションを有効にすることで、bash でも同様の zsh の動作を再現できます:

○ → echo bin/rake plugin:spec[discourse-solved]
bin/rake plugin:spec[discourse-solved]

○ → shopt -s failglob

○ → echo bin/rake plugin:spec[discourse-solved]
bash: no match: plugin:spec[discourse-solved]

(正しい方向へ導いてくれた @j.jaffeux@pmusaraj、そして bash の例を提供してくれた @supermathie に感謝します :heart_eyes:

期待通りに動作させるには、rake の引数全体を引用符で囲む必要があります。

% bin/rake "plugin:spec[discourse-solved]"

OUCH。これは、問題の原因を特定する方法を全く知らない人々にとって、多くの苦痛を引き起こすことになるでしょう。彼らがこのトピックを見つけられることを願っています。

ほとんど問題ありません。スクリプトで bash を指定すれば、手間を避けられます。

その通りですね。だからこそ、私の bash スクリプトはすべて #!/usr/bin/env bash で始まっています。Mac で実行されることは想定していないのですが :wink:

あるいは、ZSH の設定にエイリアスを追加することもできます。:slight_smile:
これは Linux で動作するため、macOS でもおそらく動作するでしょう。

alias rake='noglob rake'