494

How do you remove a file whose filename begins with a dash (hyphen or minus) -? I'm ssh'd into a remote OSX server and I have this file in my directory:

tohru:~ $ ls -l
total 8
-rw-r--r--    1 me  staff  1352 Aug 18 14:33 --help
...

How in the world can I delete --help from a CLI? This issue is something that I come across in different forms on occasion, these files are easy to create, but hard to get rid of.

I have tried using backslash

rm \-\-help

I have tried quotes

rm "--help"

How do I prevent the minus (dash or hyphen) character to be interpreted as an option?

Astra
  • 5,043
  • 2
    Would be great if this question was renamed to "How to delete a file whose name starts with --". – Sandy Sep 02 '10 at 21:04
  • @Sandy Agreed; I normally dislike changing a question's meaning, but in this case the accepted answer is specific to this problem – Michael Mrozek Sep 02 '10 at 21:52
  • 45
    i find it a bit ironic that rm --help actually explains how to delete filenames beginning with a -. good question nevertheless. – Lesmana Sep 03 '10 at 06:44
  • @lesmana irony indeed :D. I think there is a good lesson to be learned here (read the help - it may indeed be helpful). – jw013 Dec 26 '11 at 21:45
  • 3
    @jw013 Sometimes the help is easy for experienced users to understand, but overwhelming and confusing to newbs. – iconoclast Jun 13 '12 at 03:37
  • 3
    I ran into this on a system using rm from BusyBox. Everything is minimal, including the help, so rm --help did not provide any clues. – dslake Mar 19 '16 at 23:35
  • Ironically, --help isn't always helpful. OS X: rm --help returns rm: illegal option -- - and usage: rm [-f | -i] [-dPRrvW] file .... BusyBox returns Usage: rm [-irf] FILE.... The rm -- $file trick is mentioned in the man page on OS X, but most embedded systems don't bother installing the man pages. – Robert Calhoun Nov 19 '20 at 22:36
  • Achievement unlocked: How did we get here – Maciej Bledkowski Dec 28 '22 at 21:16

10 Answers10

731

Use "--" to make rm stop parsing command line options, like this:

rm -- --help
Vegar Nilsen
  • 7,481
  • 2
    Do all versions of the rm command support the -- argument? – Keith Thompson Dec 06 '11 at 07:18
  • 4
    @KeithThompson -- is a feature of most GNU tools, so it won't work on most non-GNU ("non-Linux") Unix'es (e.g. BSD variants or some embedded systems) – dtech Apr 06 '13 at 17:00
  • 1
    THANKS! That saved my day. And of course it works on BSD (OSX) and with other commands! – raskhadafi Dec 02 '13 at 08:46
  • It works with IBM AIX's old school System V UNIX coreutils. It is safe to say it will work anywhere. – RAKK Jan 29 '15 at 09:08
  • 8
    @dtech, getopt() and -- predate GNU (SysIII, 1980) and are standard/POSIX. Standard utilities except for a few exceptions (like echo) understand --. YMMV for other commands if they don't use the getopt() API to parse options. – Stéphane Chazelas Jun 17 '15 at 12:08
  • It works on the rm that's included with BusyBox, found on IoT devices (Raspberry Pi, Intel Edison, etc), Android phones, tablets, and other devices like Amazon Fire and even hacked Wii systems. – dslake Mar 19 '16 at 23:37
  • Is there any downside to always using rm [options] -- [file] in environments that allow it? – WAF Jun 21 '16 at 16:32
299

Or you can do

rm ./--help
edfuh
  • 3,091
48

Use find to do it:

find . -name '--help' -delete

And this is a good method because if you have more then a few files like this that you can delete you can get a preview list of the files by simply running find without the -delete option first, and then if the list of files look good just run it again with -delete.

In fact, you avoiding rm in favor of find (especially with preview first) is a good habit that will help you avoid mistakes with rm * that will inevitably bite you some day.

Note, though, that find will recurse through all your subdirectories, so you might want to run it with a subdirectory depth constraint like this:

find . -maxdepth 1 -name '--help' -delete

which limits the find to the current directory.

aculich
  • 1,180
  • Portably, you need to give find a list of files/dirs to look into. So find . -name.... -delete and -maxdepth are not standard options either. – Stéphane Chazelas Jun 17 '15 at 12:17
20

The answers of Vegar Nilsen and edfuh are very good and the proper solutions to a problem like this.

I do want to add a general response to this question that allows you to delete any file with a difficult file name. First its inode number is obtained using ls -i or some form of stat and then the file is removed by searching for files in the current directory by inode number and executing the rm command on the file or files with a matching inode number:

find . -inum <inode> -exec rm -- {} \;

Since inode numbers are unique in each file system you can remove any file using this; unicode or using escape characters. It is how ever very annoying to type out so I would recommend adding the line

TAB: menu-complete             # Tab: Cycles through the command
"\e[Z": menu-complete-backward # Shift-Tab: Cycles backwards

into your .inputrc file if you're using bash. This allows you to cycle through the list of possible completions (for further information).

ilkkachu
  • 138,973
Baldur
  • 317
  • 6
    This way has two problems: 1) do not use -exec rm when you can use -delete; 2) obtaining the inode and using that is needlessly overcomplicated when you can just use: find -name '--help' -delete – aculich Dec 06 '11 at 01:36
  • I don't think that will work. It traverses all the files in the current directory and all its subdirectories, and after all that it still invokes rm --help, which still won't remove the file. Just use rm ./--help (or rm -i *. – Keith Thompson Dec 06 '11 at 07:16
  • 1
    @KeithThompson find prefixes the command line argument path to all files, so it would run rm ./--help and rm ./sub/dirs/--help. To fix the second, one would have to add -maxdepth 1, but all of this is essentially applying @edfuh's solution in a more roundabout, convoluted way, and -delete is safer than -exec rm anyways. – jw013 Dec 26 '11 at 21:39
  • 2
    One more issue with this command is that there must be a space between {} and \;, otherwise it won't work. – Eugene S May 22 '12 at 14:08
  • inodes may be unique but there may be several directory entries with the same inode. Those are called hardlinks. And they're only unique per file system, so you'd need to use -xdev. That won't help you to run that ls -i --help. – Stéphane Chazelas Jun 17 '15 at 12:16
  • sigh, first, it's -inum and not -inode in at least the GNU and FreeBSD versions of find; second, -inum isn't magic, the file still gets passed by name to rm or unlink(), though here, using . as the start point will cause rm to get the filename ./-foo, bypassing the problem; third, you need a space between {} and \;. – ilkkachu Oct 22 '21 at 17:16
11

A brutal solution:

perl -e "unlink '--help' or die 'Could not unlink.';"

perl -e "rmdir '-d' or die 'Could not rmdir.';"
8

Linux Walkthrough of creating a file with dashes and spaces, then removing it.

BE CAREFUL! Don't accidentally run a rm -rf / or similar cascade delete command.

If your file you are trying to remove includes asterisks or slashes, do not accidentally pump a . or /* or * or some other wildcard which could cascade delete your operating system.

Create a file called "--yo yo"

eric@dev ~ $ touch -- "--yo yo"
eric@dev ~ $ ls
bin  --yo yo

First, find it with find:

eric@dev ~ $ find . -name "*--yo yo*"
./--yo yo

Make sure the find command ONLY finds the ONE file you want to delete:

Then pass the -delete option to find, to delete them:

eric@dev ~ $ find . -name "*--yo yo*" -delete
eric@dev ~ $ ls
bin  

Aaaannd it's gone.

2

Midnight Commander (mc) is the easiest, just point at it and hit F8 ;)

Marcin
  • 1,597
  • 3
    The OP wants a command line (CLI) solution. –  Sep 14 '12 at 13:11
  • 1
    Midnight Commander IS a CLI solution. Just use your package manger to install it. (It even works over ssh...) http://en.wikipedia.org/wiki/Midnight_Commander – daviewales Sep 20 '13 at 00:41
  • 6
    How is apt-get install mc || yum install mc; mc various arrow keys and F8 easier than rm ./--help? – Josh Dec 11 '14 at 16:33
  • 4
    @daviewales: Midnight Commander is started from the command line, and it runs in the terminal, but all keyboard actions within Midnight Commander are not from the CLI (Command Line Interface) - they are from Midnight Commander's Interface. - Typically, command line utilities can be run within a script (an exception is bash command line history) – Peter.O Aug 17 '15 at 21:33
1

here's a solution that i had used before finding this thread.
use vim to 'edit' directory:

vim .

then (in vim) select your file, hit del and confirm deletion.
when you're done quit vim with :q

atti
  • 195
-1

Have you tried to add the directory name as prefix:

$ rm ./-filename.txt dirname/-filename2.txt
$ mv ./-filename.txt filename.txt
$ cp teste ./-teste

Using the directory as prefix of the file in general helps avoiding the wrongly interpretation of the "minus" character as a command option by the parser function.

perror
  • 3,239
  • 7
  • 33
  • 45
-4

If you want to rename the file, -.bar, (mv won't work), try this:

cat >foo.bar <-.bar

before using the command:

rm -- -.bar

You should be able to examine the original file's contents in foo.bar

Mat
  • 52,586