Solving "zsh: no matches found" error when running rake task

macOS now ships with zsh as the default shell, which means this issue comes up fairly regularly.

In zsh:

% bin/rake plugin:spec[discourse-solved]
zsh: no matches found: plugin:spec[discourse-solved]
Why does this happen?

This is because the square brackets are interpreted as a glob pattern. In bash, the glob fails to match a pattern, but the command is executed anyway and it works. In contrast, zsh raises an error and does not execute rake.

To illustrate, in 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

You can replicate the zsh behaviour by enabling the failglob option in bash:

β—‹ β†’ 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]

(thanks @joffreyjaffeux and @pmusaraj for pointing me in the right direction, and @supermathie for the bash examples :heart_eyes:)

To make it work as expected, you need to wrap the whole rake argument in quotes

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

Ouch. That sounds like it’s going to cause a bunch of pain to people who are not likely to have any idea how to figure out the problem. Hopefully they’ll find this topic.

3 Likes

It’s mostly fine - scripts can just specify bash to avoid any pain.

2 Likes

True enough. I guess that’s why all of my bash scripts start with #!/usr/bin/env bash even though I don’t expect them ever to run on a Mac :wink:

2 Likes

Or, you could add an alias to your ZSH config. :slight_smile:
That works on Linux, so it will probably work on macOS as well.

alias rake='noglob rake'
6 Likes