That would be the first time I see anybody complaining about that (we more often see people complaining about it not doing word splitting upon parameter expansion).
Most people expect
to output the content of the
$file variable and are annoyed when shells like
bash don't (a behaviour inherited from the Bourne shell, unfortunately not fixed by ksh and specified by POSIX for the
sh interpreter), and that's causing a lot of bugs and security vulnerabilities and that's why you need to quote all the variables in those shells.
See for instance: Security implications of forgetting to quote a variable in bash/POSIX shells
I see that you're expecting that too as you're writing
echo $0 and not
zsh has fixed that. It does neither globbing nor word splitting by default upon parameter expansion. You need to request those explicitly:
echo $=file: perform word splitting
echo $~file: perform globbing
echo $=~file: perform both
Or you could turn on the
shwordsplit options to get the same behaviour as in Bourne-like shells (those two options are enabled when
zsh is invoked as
sh compatibility), but I would not recommend that unless you need
zsh to interpret code written for another shell (and even in that case, it would make more sense to interpret that code in
sh emulation in a local context with
emulate -L sh).
Here naming your variable
is misleading if you intend it to be expanded upon expansion¹
would make more sense. If you want a variable holding the name of all the non-hidden files in the current directory, you'd do:
for that assignment not to fail if there's no non-hidden file in the current directory.
That is, use an array variable assignment. That (
file=(*)) would work the same as in
yash, except that
zsh doesn't have that other misfeature of the Bourne shell whereby the pattern is left unexpanded when there's no match.
* is a perfectly valid name for a file on Unix-like system. I take some comfort in that
rm -f -- $file removes the file whose name is stored in
$file even if that file is called