Dangers of wildcards in bash

Many web developers and some filemaker developers likely use bash while using the terminal.  You may have come across some odd issues when you use a command like “rm *”, when you’re in a folder with a lot of files or a file that starts with dash.  The challenge is that bash expands * to be a list of the files and folders rather than passing it on the command.  The issue with a lot of files is there’s a max command length and the issue with files that start with a dash is the command your trying to call might think your trying to pass it a argument and not a file.  This feature can get fun when you use something like gnu tar.

There’s a nice write-up of the feature/issue here.

	$ touch -- "--checkpoint=1"
	$ touch -- "--checkpoint-action=exec=sh shell.sh"
	$ echo "whoami" > shell.sh
	$ touch a
	$ sudo tar cf archive.tar *
	root

What happens when you run “tar cf archive.tar *” is bash turns that into “tar cf archive.tar a --checkpoint=1 --checkpoint-action=exec=sh shell.sh  shell.sh“.  GNU tar tries to be as helpful as it can process each -- parameter in to something it should act on regardless of where it is in the command.

The question quickly becomes “What should I do to prevent issues like this?”.  For most commands there’s two methods around it.  The first is prefix the * with ./ (tar cf archive.tar ./*) because that will cause bash to prefix what’s passed with ./.  The second solution that works with most commands is pass -- before the * (tar cf archive.tar -- *) as most commands take that as a hint that everything that’s after it is a filename.

Have questions? Let us know in a comment below, or contact our team directly. You can also check out our other posts on software development.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top