Hyphens in UNIX filenames
Today I discovered an interesting UNIX design flaw. UNIX deals badly with files starting with
-. Let’s mess around!
Warning: do like me, create a new directory and
cd into it.
$ mkdir tests && cd tests $ touch -r touch: usage: touch [-alm] [-t time_t] <file>
Okay, so I can’t create a file starting with a
touch thinks it’s an argument. There are several ways around to create this file:
$ touch ./-r
Here you give it a path, so that the first argument
touch gets is not a
-. The path here (
./) is a relative path, it’s the directory I’m currently in.
That’s the best method, but there are others.
$ touch -- -r
Some touch implementations allow the user to write
-- between the options and the filename. This method doesn’t work everywhere, not with BusyBox for example, that’s why I prefer the method above.
$ touch r $ mv r -r
This also works.
Okay, whatever the reason to create that file is, I finally have it. Yay!
Create a directory, we’ll see after why.
$ mkdir tre $ ls -l ----rwxr-x system sdcard_rw 0 2014-08-03 15:22 -r d---rwxr-x system sdcard_rw 2014-08-03 15:22 tre
Everything’s there, that’s cool, but now I want to delete everything in the directory, except subdirectories.
$ rm * $ ls -l ----rwxr-x system sdcard_rw 0 2014-08-03 15:22 -r
Wait, what ?
-r should have been deleted, not the directory
In fact, when I run that command, the shell transforms
* into the list of files in the directory, then gives it to the program. In that case, there’s one file:
-r, but the program
rm has no way of knowing that
-r is a file, not an argument. And even if you have other files in your directory, filenames starting with
- always are first in the list of arguments, that’s standard.
It’s the end of this article, let’s delete that file!
$ rm -r $ ls -r
Yes, method for creating and deleting that kind of files are the same, obviously this doesn’t work. But now it shouldn’t be hard for you to delete it, right?