6

I have been creating odd-named files every once in a while, e.g.

$ls -rthl
$-rw-r--r--  1 shamil hep  290 Aug 13 11:58 -rf

And interestingly it is impossible to remove this file with

rm -f -rf

I know I need to escape the special symbols like "-", so the issue is clear. And I used to know the solution, but have since forgotten.

How do I properly delete it?

I have tried things like this

rm -f \-rf

but to no avail.

Chikipowpow
  • 173
  • 6

3 Answers3

15

-- switch means: End of flags, everything after it is assumed to be a file name. So you can do:

rm -- -rf

Include the full path to the file also works:

rm /full/path/to/-rf

Actually, this is kind of hilarious but this command line can give you the answer :)

$man rm | cat | grep -B4 -A3 -- "rm --"

To remove a file whose name starts with a `-', for example `-foo', use 
one of these commands:

rm -- -foo
rm ./-foo
Paulo Bu
  • 288
  • 3
  • 8
  • 1
    This won't work with all commands. – Donovan Dec 17 '13 at 20:25
  • Please can you provide an example? I was quoting the `man bash` there. – Paulo Bu Dec 17 '13 at 20:26
  • @PauloBu `man rm` in `bash`? –  Dec 17 '13 at 20:28
  • 1
    @MadPhysicist not, actually I quote `man bash`. But seeing `man rm` there is a line that tells you that: `man rm |cat |grep -B4 -A3 -- "rm --"` – Paulo Bu Dec 17 '13 at 20:33
  • The double dash trick is handled by the command line processing library. It is not guaranteed to work all of the time. Try this script `#!/bin/sh for i in $@ do echo $i done` – Sean Perry Dec 17 '13 at 23:00
  • @Donovan `--` works with all commands that respect the option parsing conventions, which is almost all of them. – Gilles 'SO- stop being evil' Dec 18 '13 at 09:51
  • @SeanPerry This script doesn't accept any options. (It's also missing some essential quoting, to do something halfway sensible.) Almost all commands do accept options and do obey the [conventions](http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap12.html#tag_12_02). – Gilles 'SO- stop being evil' Dec 18 '13 at 09:54
  • 2
    Whether this convention works with all commands is irrelevant, and a different answer to a different question. **The questioner specifically asked about `rm` and deleting files** and a way to invoke `rm` that xe had forgotten. Paulo Bu's answer deals specifically with that, even quoting the manual for `rm` where the questioner would have found xyr answer. Its major problem is a Useless Use Of `cat`. (-: – JdeBP Dec 18 '13 at 13:38
  • I also offered another alternative which might work whether the shell support `--` or not. That is the full path. Anyways, I hope someone find my answer useful :) – Paulo Bu Dec 18 '13 at 13:46
8

You can do

rm -rf ./-rf

This will make it so that -rf does not start with a -.

Jawa
  • 3,619
  • 13
  • 31
  • 36
Mad Physicist
  • 4,320
  • 2
  • 15
  • 15
2

another way:

find -name "-rf" -exec rm {} \;
BMW
  • 166
  • 6
  • This relies on undocumented behavior of `find` -- do you have any information regarding how many variants of *nix support it? Anyway, it’s just a roundabout way of saying `rm ./-rf`. – Scott - Слава Україні Dec 18 '13 at 00:28
  • @Scott `find` without a directory argument is specific to Linux (both GNU and BusyBox) and is equivalent to `find .`. The names listed by `find .` obviously don't start with `-` since they start with `./`. – Gilles 'SO- stop being evil' Dec 18 '13 at 09:55
  • But that’s my point – how do you know that `find . … -exec …` _builds command arguments_ beginning with `./`? Sure, you might guess that it does, from the behavior of `find . … -print` (in contrast to, for example, `ls .` or `ls -l .`), and maybe it is standard, but it’s not documented. – Scott - Слава Україні Dec 18 '13 at 17:14