If you’re managing many Unix systems, you come across files with special characters – they can’t be deleted with rm command using standard approach and require a bit of trick to be successfully removed.
Examples of files with special characters dash (-) and hash (#)
RHEL$ ls -al
-rw-r--r-- 1 root root 0 Jun 25 05:50 #test
-rw-r--r-- 1 root root 0 Jun 25 05:48 -test
Now, if you test to access these files or remove them, you will get errors:
RHEL$ cat -test
cat: invalid option -- r
test `cat --help' for more information.
RHEL$ rm -test
rm: invalid option -- t
test `rm ./-test' to remove the file `-test'.
test `rm --help' for more information.
These errors happen because commands treat file names as command line options because they start with dash (-).
With filenames starting with hash (#), you’ll get a different kind of error: your Unix shell will treat the rest of a filename (and anything that might follow it) as a comment because hashes are used to do it in shell scripts. That’s why your cat command will not show any error but will not finish until you Ctrl+C it:
RHEL$ cat #test
… and if you test removing such a file, you’ll get a complaint from the rm command about missing command line parameters – because of the hash (#) sign, rm command receives no text as a parameter:
RHEL$ rm #test
rm: missing operand
test `rm --help' for more information.
How to remove a file when filename starts with dash (-)
First I’m gonna show you how to make your Unix shell interpret any filename directly instead of testing to analyze it as a set of command line options.
To make command ignore the leading dash (-) in a filename, use the — command line option:
RHEL$ rm -- -test
As you can see, our file is gone:
RHEL$ ls -al
-rw-r--r-- 1 root root 0 Jun 25 05:50 #test
Using backslash to escape special characters in a filename
Another option we have is to use a backslash (), which will make shell interpreter ignore the special functionality of a character which immediately follows it. To escape the hash (#) our second file has, we should therefore do the following:
RHEL$ rm #test
Interesting to know: bash shell has an auto-completion functionality built in. When you type a filename, just press Tab key to make it auto-complete the name for you. Speaking of special characters in particular, quite a few of them are recognized by auto-completion and get escaped automatically.
So, if you start typing:
RHEL $ rm #t… and then press Tab, bash will not only auto-complete the name, but escape the leading hash (#):
RHEL $ rm #test