29

I was wondering how to make a file named as a flag, e.g., if I wanted to make a folder named -a, what commands would do the trick?

I tried mkdir '-a', mkdir \-a, and neither worked. I'm on Ubuntu.

Jens Erat
  • 17,507
  • 14
  • 61
  • 74
MYV
  • 1,163
  • 3
  • 14
  • 22
  • 13
    The answers here are all great, but I can't think of a non-troll reason to want to do this... – evilsoup May 26 '13 at 12:55
  • @evilsoup Some people like to prefix folders so they stick at the top in a listing sorted alphanumerically. But that's the only reason I can think of, to be honest. – slhck May 26 '13 at 13:39
  • @slhck I know of at least one video editing course where they encourage students to append blank spaces to their projects' directories so they'll show up at the top on communal iMacs. This was ugly and led to hilarious escalation, but at least it wouldn't be potentially system-breaking... – evilsoup May 26 '13 at 13:44
  • 3
    Mostly this is here for academic interest. – MYV May 26 '13 at 15:22
  • 5
    Obligatory comic: http://beesbuzz.biz/d/20110224.php – fluffy May 26 '13 at 18:48
  • [How to remove a file with name starting with “-r” using cli](https://superuser.com/q/689825/241386), [Unix: Files starting with a dash, -](https://superuser.com/q/120078/241386), [How to open files with forward dash in linux](https://superuser.com/q/603792/241386), [Can't rename a file the name of which starts with a hyphen](https://superuser.com/q/510337/241386), [How do I delete a file whose name begins with “-” (hyphen a.k.a. dash or minus)?](https://unix.stackexchange.com/q/1519/44425) – phuclv Aug 20 '18 at 05:39

4 Answers4

49

Call the command like so:

mkdir -- -a

The -- means that the options end after that, so the -a gets interpreted literally and not as an option to mkdir. You will find this syntax not only in mkdir, but any POSIX-compliant utility except for echo and test. From the specification:

The argument -- should be accepted as a delimiter indicating the end of options. Any following arguments should be treated as operands, even if they begin with the '-' character. The -- argument should not be used as an option or as an operand.

Using -- as a safeguard is recommended for almost any action where you deal with filenames and want to make sure they don't break the command, e.g. when moving files in a loop you might want to call the following, so that a file called -i isn't (in?)correctly parsed as an option:

mv -- "$f" new-"$f"
slhck
  • 223,558
  • 70
  • 607
  • 592
  • The downside of this approach is precisely that it terminates options processing. For a simple mkdir example, that works wonders; if you actually need an option to follow the file name on the command line, it won't work at all. – user May 26 '13 at 13:20
  • 1
    Of course—there's a downside to everything. In cases where you deal with file names interspersed with options, [Amos' solution](http://superuser.com/questions/600066/how-to-create-a-file-which-is-named-like-a-command-line-argument#answer-600080) would be the only sane alternative I can think of, but it really depends on how the tool parses options. – slhck May 26 '13 at 13:31
  • 1
    Since the OP talks about creating a *file* with a name "like a command line argument" (let's assume meaning a name beginning with a hyphen), I don't think that's an entirely unreasonable assumption. Take `cc -o -myfile -Wall -myfile.c` as an only slightly contrived example. Any editor worth its salt should be able to save to a file named `-myfile.c` if you ask that of it, but the C compiler will probably not do what you want when given such a list of options. – user May 26 '13 at 13:33
  • True. Then again, what sane person would ever want to do this… ? But that's probably out of scope here and a principal issue with the question itself. If the root problem is making commands *safer* though, there are multiple viable ways to achieve that, depending on the context. The `--` is just easy to throw in most of the time. – slhck May 26 '13 at 13:49
  • When would you need options to follow a filename? Why cant you just put everything you need before the double dash? – MYV May 26 '13 at 15:25
  • 1
    @Maksim For example commands that require an option to set an input or output filename, like the `cc` command Michael gave above, which has the `-o` option to specify the output file. – slhck May 26 '13 at 15:46
  • @Maksim `find` seems like another obvious possibility where you might want to put more options after a file name. – user May 26 '13 at 19:10
  • 1
    The loop example is why you should always use something like `for f in ./*; do...` rather than `for f in *; do...` – evilsoup May 26 '13 at 23:49
  • This suggests the question, how do you create a file called `--`? – jwg May 27 '13 at 10:02
  • @jwg The same way: `touch -- --`. – slhck May 27 '13 at 10:07
  • The POSIX specification that you quote says "The -- argument should not be used as an option or as an operand." – jwg May 27 '13 at 10:11
  • @jwg … but not if you *already* treat everything like an operand. This guideline doesn't mean you shouldn't create a file called `--`, but you should not create a program that accepts `--` as a valid option or operand if not used to signify the end of options. – slhck May 27 '13 at 10:15
21

The simplest way that should work with any reasonable program is to use a relative path name in front of the -, e.g. mkdir ./-a will create a directory called -a in the current working directory.

The most common example of using this "trick" is when you want to remove a file which begins with a dash, so you can do rm ./-a.

slhck
  • 223,558
  • 70
  • 607
  • 592
Capt. Crunch
  • 458
  • 1
  • 3
  • 13
  • 3
    That of course only does the trick if you're working with file paths, and not any arbitrary command line options that are parsed as strings. But otherwise prefixing `./` is always a good idea—imagine you created a file called `-rf` and then you called `rm *`. – slhck May 26 '13 at 10:33
  • 1
    @slhck To many people that might look a joke. But I have seen enough cases where this sort of thing wiped out (part of) a server. You can't warn people enough about the dangers of files starting with a dash. One place I worked even had it as an official rule: Never ever create a file whose name starts with "-f" or "-r". – Tonny May 26 '13 at 15:05
  • 1
    This one should be the answer : it is the only portable way (`--` is not understood by every commands, just a few) – Olivier Dulac May 27 '13 at 12:11
  • @OlivierDulac I thought the `--` was a bash thing, so it should work for all programs? – gsgx May 30 '13 at 22:29
  • @gsingh2011 no, the code which decides whether "--" is regarded as an "end of flags" marker lives in the application and it's up to each application to decide whether it treats it that way. – Capt. Crunch May 31 '13 at 01:58
  • @gsingh2011: scripts using getopt (not getopts) have "--", and many C programs include its handling as well (not sure via which librarys...). But it's far from being all programs (and especially for older systems : many won't know about '--', even programs that now do) – Olivier Dulac May 31 '13 at 08:35
4

The reason why mkdir '-a', or mkdir \-a doesn't work is because both of these methods (using quotes or backslashes) are used to prevent your shell (likely bash) from giving them any special meaning. Since -a doesn't mean anything special to the shell anyway, these have no effect on how it gets passed on to mkdir.

As far as mkdir is concerned, it receives a list of arguments from the shell, and it can't tell whether you put them in quotes or not, or whether there was a backslash. It just sees one argument -a. That's why you need the -- as explained in the other answers.

hammar
  • 271
  • 1
  • 8
-3

In addition to the answer from "slhck" there is another trick that sometimes works:

Put the filename in question within 2 sets of (different) qoutes like "'-a'" or '"-a"'.

Whether or not this works depends on the program, but it is a last resort if the program doesn't support the POSIX -- feature.
The POSIX method is always preferred as it is 100% reliable.

Tonny
  • 29,601
  • 7
  • 52
  • 84
  • *"The POSIX method is always preferred as it is 100% reliable."* Using `--` to terminate options processing also assumes that you don't need any options to follow the file name, which is not always the case. – user May 26 '13 at 13:19
  • @MichaelKjörling Of course... But I sort of assumed that would be obvious. – Tonny May 26 '13 at 15:00
  • 4
    This will create a file called `'-a'` or `"-a"`, at least on BSD-type systems – nohillside May 26 '13 at 15:27
  • @patrix As I said: It depends on the program, the OS and even the shell that is used. It's by no means guaranteed to work. – Tonny May 26 '13 at 17:16
  • 4
    Can you cite an OS/shell where this *does* work? – nohillside May 26 '13 at 19:07
  • 1
    if it did work, it would seem you'd have a rather significant problem dealing with files with names surrounded by quotemarks. – muhmuhten May 27 '13 at 04:43