This is a glob used as a command name

SC2211: a glob pattern like `*.sh` appears where a command name is expected. Usually a missing loop or misplaced quote.

Problem

When Bash sees a glob where a command should be, it usually means the author meant to loop over matching files or pass the glob as an argument. A bare `*.sh` as the first word of a command expands to filenames and then tries to execute the first match as a command — almost never what you want.

Bad

*.sh                    # tries to run the first .sh file as a command
./scripts/*.sh --help     # same problem

Good

for script in ./*.sh; do
  [ -e "$script" ] || continue
  echo "running $script"
  bash "$script" --help
done

Explanation

Globs belong inside loops, assignments, or arguments. If you want to run every matching file, use an explicit loop. If you want to run one specific script, name it directly.

Related

SC2012

SC2044

When It Matters

A glob in command position expands against the current directory before the shell decides what to run, so "rm *" as a typo for a function name, or a pattern that matches an executable file, runs whatever the glob happened to find. When it matches nothing, the shell tries to execute the literal pattern and reports a confusing "command not found" containing an asterisk. Most occurrences are a mistyped command name or a missing quote around an argument that drifted into the first position.

Second Example

Note

Quoting a command name stored in a variable — "$cmd" — keeps it a single word and prevents both globbing and word splitting.

Exceptions

There is no legitimate reason to leave a glob in command position. If the command name is dynamic, hold it in a variable and expand it quoted, or use an array for the whole command line: cmd=(rsync -a) then "${cmd[@]}" src dst.

Faq

Q

Why does the shell say "command not found: *.sh"?

A

Because the glob matched nothing, so the pattern was left literal and the shell tried to execute a file with that exact name.

Q

How do I store a whole command safely?

A

Use an array: cmd=(docker run --rm image) and invoke it as "${cmd[@]}". A plain string would need eval, which reintroduces quoting bugs.

Q

Does quoting prevent glob expansion?

A

Yes. Quoted text is never subject to pathname expansion, in command position or anywhere else.