Today is going to be a practical tip. If you're managing many
Unix/Linux systems, sooner or later you come across files with
special characters – they can't be deleted with
rm command
using standard approach and require a bit of trickery to be
successfully removed.
Examples of files with special characters
Any language apart from English will probably have special
characters in the alphabet, but for the purpose of today's exercise
I'll give you more standard examples: files starting with dash (-)
and hash (#) characters:
rajat-linux$ ls -al
-rw-r--r-- 1 rajat admin 0 Sep 25 05:50 #try
-rw-r--r-- 1 rajat admin 0 Sep 25 05:48 -try
Now, if you try to access these files or
remove them, you will get errors:
rajat-linux$ cat -try
cat: invalid option -- r
Try `cat --help' for more information.
rajat-linux$ rm -try
rm: invalid option -- t
Try `rm ./-try' to remove the file `-try'.
Try `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:
rajat-linux$ cat #try
… and if you try 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:
rajat-linux$ rm #try
rm: missing operand
Try `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 trying 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:
rajat-linux$ rm -- -try
As you can see, our file is gone:
rajat-linux$ ls -al
-rw-r--r-- 1 rajat admin 0 Sep 25 05:50 #try
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:
rajat-linux$ rm \#try
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:
rajat-linux $ rm #t
… and then press Tab, bash will not only auto-complete the name,
but escape the leading hash (#):
rajat-linux $
rm \#try
There's a few more tricks you can use for escaping special
characters, but they're worth a separate post, so stay tuned! Until
then, enjoy getting rid of annoying files with special characters in
filenames!