Today I received an interesting question:
“How to remove files that start with a hyphen, dash or a minus?“
Although I knew how to create one, I assumed that these files can be removed by escaping the dash. Well, I was wrong, just use the same method that you use to create them! Or use the bash man page to find the answer! Here is how to create a file:
[cristian@ares ~]# touch /home/cristian/-file-that-starts-with-a-dash-hyphen-or-minus [cristian@ares ~]# ls -alh /home/cristian/-file-that-starts-with-a-dash-hyphen-or-minus -rw-r--r-- 1 root root 0 Aug 12 19:24 /home/cristian/-file-that-starts-with-a-dash-hyphen-or-minus [cristian@ares ~]#
And here is how to remove it:
[cristian@ares ~]# rm ./-file-that-starts-with-a-dash-hyphen-or-minus rm: remove regular empty file `./-file-that-starts-with-a-dash-hyphen-or-minus'? y [cristian@ares ~]#
All you need to do is provide is the absolute path or the relative path to the file when you create it or when you remove it. What you get when you try to escape the file:
[cristian@ares ~]# touch \-some-file-that-starts-with-a-dash-hyphen-or-minus touch: invalid option -- 's' Try `touch --help' for more information.
Ok, the explanation is simple, I had to stress myself a little bit to find one. When you escape something (usually in a script) is to prevent it to be interpreted by the shell, well in this case it’s the binary (touch and rm) which ignores the escaped character and gets the first string of the file as an option! Another method is described in bash manual page, use to mark the end of options
-- (double hyphen/dash/minus)
SHELL BUILTIN COMMANDS       Unless otherwise noted, each builtin command documented in this section as accepting options preceded by – accepts — to signify the end of the options. The :, true, false, and test builtins do not accept       options and do not treat — specially. The exit, logout, break, continue, let, and shift builtins accept and process arguments beginning with – without requiring –. Other builtins that accept arguments       but are not specified as accepting options interpret arguments beginning with – as invalid options and require — to prevent this interpretation. So using
rm -- -some-file-that-starts-with-a-dash-hyphen-or-minus
will work just fine