シェルの仕事、コマンドの仕事

コマンドが受け取る前に、シェルが * を該当ファイル全部に展開している
コマンドが受け取る前に、シェルが * を該当ファイル全部に展開している

ls *.txt と入力したとき、ls コマンドに *.txt という文字列が渡されるわけではない。シェルが先に *.txt をファイル名に展開し、ls file1.txt file2.txt notes.txt という形で ls に渡している。

つまり ls は自分がワイルドカードで呼ばれたことを知らない。cp、mv、rm でもグロブが使えるのは、展開がコマンドではなくシェルの仕事だから。どのコマンドでも同じ仕組みが働いている。

だからマッチするファイルが1つもないとき、bash はパターンをそのまま文字列として渡す。ls *.xyz が「ファイルが見つかりません」になるのはそういう理由だ。zsh は既定では、ls を呼ぶ前にシェル自身が「no matches found」と言って止める。