Asterisks are f****** dangerous


TL;DR: command * ❌, command ./*

I do a lot of mv with asterisks (*) in the shell on my server / NAS to manage files.

I used to just do mv ./* /destination/ because that’s just what I learnt but about a day ago I thought “why type all this when I can just do mv *? It took just a day to learn why that’s a very bad idea.

When managing more files with mv today, I was greeted with this:

function@server:~$ mv * /destination/
mv: invalid option -- 'r'
Try 'mv --help' for more information.

Huh? How can this command have any issues, it’s literally like 5 characters and a destination path.

Turns out that “shell expansion” (which I’ve heard before) should be taken very literally. If a file like --r.txt (totally valid filename btw) exist in the path where you’re using the asterisk, the shell will literally expand the asterisk to --r.txt in the command line - like an actual argument to your command.

This is not restricted to mv - this applies to everything. In my case, nothing bad happened, but imagine using something like rsync + * (for some reason) and that * expands a file called --delete into your shell. Okay, okay, that’s a bit contrived, but you get what I mean.

If you instead use ./* the shell would expand the asterisk to ./--r.txt instead, which would be safe.

I really hope none of you ever learn this the hard way. By the way, mv overwrites files by default without asking (what the f***?), so I recommend always passing -i for interactive prompt on conflicts or -n for no overwrite (should be default imho).