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.

6
  • 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, 2013 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, 2013 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, 2013 at 13:44
  • 3
    Mostly this is here for academic interest.
    – MYV
    May 26, 2013 at 15:22
  • 5
    Obligatory comic: beesbuzz.biz/d/20110224.php
    – fluffy
    May 26, 2013 at 18:48

4 Answers 4

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"
12
  • 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, 2013 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 would be the only sane alternative I can think of, but it really depends on how the tool parses options.
    – slhck
    May 26, 2013 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, 2013 at 13:33
  • 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, 2013 at 15:46
  • 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, 2013 at 23:49
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.

6
  • 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, 2013 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, 2013 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) May 27, 2013 at 12:11
  • @OlivierDulac I thought the -- was a bash thing, so it should work for all programs?
    – gsgx
    May 30, 2013 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. May 31, 2013 at 1:58
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.

-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.

6
  • "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, 2013 at 13:19
  • @MichaelKjörling Of course... But I sort of assumed that would be obvious.
    – Tonny
    May 26, 2013 at 15:00
  • 4
    This will create a file called '-a' or "-a", at least on BSD-type systems
    – nohillside
    May 26, 2013 at 15:27
  • 4
    Can you cite an OS/shell where this does work?
    – nohillside
    May 26, 2013 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, 2013 at 4:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .