Shell, explained

What does * mean in the terminal? Globbing explained

echo *.txt

* is a wildcard that the shell expands before the command runs: the pattern is replaced by every file name in the current folder that matches it. The command never sees the *, only the list of names.

*.txt becomes the matching names

echo never sees the pattern. It is handed three file names and prints them.

$

Tap a word to follow it

FOLDERnotes.txtphoto.pngreport.txttodo.txt
*Globs patterns become the matching file names4 words
echonotes.txtreport.txttodo.txt
*.txt→notes.txtreport.txttodo.txt

echo receives 3 arguments

1notes.txt2report.txt3todo.txt
Tap any part of the command to see what it does

When nothing matches

In bash a pattern that matches nothing is passed on as is, so ls looks for a file literally named *.xyz.

$

Tap a word to follow it

FOLDERnotes.txtphoto.png
*Globs2 words
ls*.xyz

Nothing matched, so the pattern stays. ls replies: ls: *.xyz: No such file or directory

ls receives 1 argument

1*.xyz
Tap any part of the command to see what it does

Quotes switch it off

Inside quotes * is just a character: echo prints *.txt.

$

Tap a word to follow it

FOLDERnotes.txtreport.txt
""Quote removal the quotes themselves disappear2 words
echo*.txt
'*.txt'→*.txt

echo receives 1 argument

1*.txt
Tap any part of the command to see what it does

Part by part

echo
Prints its arguments, separated by spaces.
*
Matches any run of characters in a file name, including none.
.txt
Must match literally: the name has to end in .txt.

Common mistakes

rm * .txt

One stray space turns this into rm * and rm .txt: it deletes every file in the folder. Run echo with the same pattern first to see what it matches.

Expecting * to match hidden files

* skips names that start with a dot, like .env. Match them with .* or turn on shopt -s dotglob in bash.

Try it

$ echo *

Every visible name in the folder.

$ echo report?.txt

? matches exactly one character.

$ echo [nt]*.txt

[nt] matches one of the listed characters.

Questions

Why does zsh say “no matches found”?

zsh treats a pattern that matches nothing as an error instead of passing it on. Quote the pattern (find . -name '*.txt') when you want the program to see the *.

Is * the same as a regular expression?

No. In a glob, * means any characters; in a regular expression (grep, sed), * means “repeat the previous character”. .* is the regex way to say any characters.

Does * search subfolders?

No, only the current folder. In bash, shopt -s globstar enables **/*.txt for all subfolders, or use find.

Terminaster

Ask about any command and get a picture like this one.

The Terminaster tutor draws these visuals for your own questions, then turns what you learned into spaced-repetition cards so it sticks.