The Stage
I ran a script that takes a file path as an argument and it writes to that file. First, I ran it with the -h flag to see if I could get a help message. No error message printed to stdout. However, the script then did something unexpected…
After pressing enter, the script continued execution and prompted for additional input. I didn’t notice and hit “enter” a couple of times to get a clean prompt. This inadvertently allowed the script to finish. As a result, I ended up with a brand new file call “-h”. Oops.
Deleting a file is hard…
No big deal right?
$> ls
-h
We can just delete that with a simple “rm” command
$> rm -h
rm: invalid option -- 'h'
Try 'rm ./-h' to remove the file '-h'.
Try 'rm --help' for more information.
What…?
$> rm \-h
rm: invalid option -- 'h'
Try 'rm ./-h' to remove the file '-h'.
Try 'rm --help' for more information.
$>
$> rm "-h"
rm: invalid option -- 'h'
Try 'rm ./-h' to remove the file '-h'.
Try 'rm --help' for more information.
$>
$> rm '-h'
rm: invalid option -- 'h'
Try 'rm ./-h' to remove the file '-h'.
Try 'rm --help' for more information.
$>
$> rm '\-h'
rm: cannot remove '\-h': No such file or directory
At this point, I scratched my head in confusion. However, after some Googling I found a couple of simple solutions
$>rm ./-h
# or
$>rm -- -h
Either of these solutions works. The first works because we’re using the current directory as part of the path. This tells bash not to process the hyphen as an option.
Finally, the second option works because the double hyphen is a bash built-in. It tells the command that there are no more options to process and that anything else is a positional argument.
Wrap-up
In conclusion, I have a few lessons learned:
- Actually look at your prompt before pressing enter
- Shells have a lot of nuances. It’s worth taking the time to learn about them when you encounter them because you’ll likely run into them again.
- Use “set -e” in your scripts. If there is an error, the script will exit rather than continue execution.
Top comments (8)
rm \\-h
is closer to what you may consider standard.You would think, but that's not the case. At least not in bash. I haven't tried in other shells.
Whack. Works on my machine.
Which shell are you running? Version? I would like to try it out.
Ah that might be it. I’m on zsh. I never really encountered actual shell differences before.
Just in case you can always find the file by its inode and remove it. But these variants are faster of course.
Just in case:
Nice one!
I'm going to work that into my post and credit you with that one if that's okay.
I knew you could use
ls
to see inode info, but I didn't know you could use inode info withfind
.Sure you can, but that is an old instruction, don't even remember where I have found it. Most likely on the Cybercity. What is good in this trick - you can delete the file with any naming issues either it has slashes, dashes or whatever.