4

I don't understand why * returns itself when there's no match. This answer states that this is the case, but I don't understand the rationale for this behaviour. Why doesn't *, or any generic pattern, just return an empty string in case of no match?

$ls      # Look, no files
$touch a # Add a file
$echo *  # Works as expected
a
$rm a    # Remove the file
$echo *  # Will output a '*'. Why not ''?
*
$*       # Ok, * will fail, but how come the previous output?
-bash: *: command not found
$
  • 5
    because the doc says so: If no matching filenames are found, and the shell option nullglob is disabled, the word is left unchanged; see also: echo ? – Jeff Schaller Nov 01 '16 at 17:42

2 Answers2

5

Patterns that don't match any files are considered an error. You can see this in the very first versions of unix.

glob would print an error, and the command it was passed would never be run.

The error message was "No match".

In your modern shell derived from Bourne (Unix version 7), ls -l *.c would generate the error "*.c: No such file or directory". I'd say this message is easier to understand; also it indicates the pattern which failed.

Note if *.c was expanded to empty, ls -l *.c would show all files in the directory instead, and print no error.

bash has a failglob option for behaviour closer to the original.

sourcejedi
  • 50,249
1

The * is actually being expanded by bash (whatever your shell is) and then it is passed on to the echo. The echo command does nothing but prints it to standard output. Read this document - File name expansion. It says-

Bash scans each word for the characters "*", "?", and "[". If one of these characters appears, then the word is regarded as a PATTERN, and replaced with an alphabetically sorted list of file names matching the pattern. If no matching file names are found, and the shell option nullglob is disabled, the word is left unchanged. If the nullglob option is set, and no matches are found, the word is removed.

So actually when bash cannot find any matching it left '*' unchanged and echo prints that.

Reason The reason bash doesn't return an empty statement by default cause there can be cases where the user doesn't want to use the '*' as wildcard and so he doesn't need the expansion of '*'. And hence in this case expanding the '*' to empty string would have erroneous. However this default behaviour can be overridden by nullglob option.

trishnendu
  • 314
  • 1
  • 9
  • 2
    I think the question-asker knows this, and is asking why the shell's authors made that decision rather than the alternative of returning nothing. – mattdm Nov 01 '16 at 17:54
  • I also found more info here: http://unix.stackexchange.com/questions/204803/why-is-nullglob-not-default – Fredrik Johansson Nov 01 '16 at 19:28