2

I have a habit of typing rm -rf * every time I'm in some kind of sleep mode. It seems that my subconscious wants me to delete everything I code at the end of the day.

Is there a way to block this particular command (rm -rf *) in Linux in the C-shell or bash-shell?

Alternatively, is there a way in which I can set up a command filter for my shell inputs before it goes to the shell for further processing?

4
  • 11
    Don't sleep and code?
    – Marc B
    Dec 13, 2011 at 14:33
  • 12
    Break the habit rather than seek a technological solution. It's still and counter productive. Dec 13, 2011 at 14:35
  • 7
    You seem to be searching technical solutions for psychological problems. Always try to solve a problem within its solution domain.
    – thiton
    Dec 13, 2011 at 14:39
  • I second this, if you ever ssh into my box you might accidentally kill everything. NO GOOD!
    – reconbot
    Dec 13, 2011 at 20:56

12 Answers 12

5

Check out safe-rm which is a wrapper for rm that will allow you to set up a list of important directories that cannot be accidentally deleted.

This won't stop you from accidentally deleting files outside the listed directories, but it will prevent a catastrophe when your subconscious decides to up the ante and do an rm -rf /.


That aside, the canonical way to prevent accidental deletion is to use alias rm="rm -i" as mentioned in several of the other answers.

Extreme measures for extreme situations ...

If you're subconscious is as malicious as it sounds, it can still bypass this by using /bin/rm instead to skip the alias. For some safeguard against this, create a file called -i in the directories you work in often:

[me@home]$ touch -- -i
[me@home]$ ls
-i    file1.txt    file2.txt

When evil-you does /bin/rm -rf *, the wildcard gets expanded to the list of files which starts with -iand that will be seen as an option by /bin/rm:

[me@home]$ /bin/rm -rf *
/bin/rm: remove regular empty file `file1.txt'?

(mouse-over the following block when your subconscious is not looking...)

Now let's hope your subconscious is not aware of the -- option...

4

You should be able to do that using the alias command. That's the same thing that e.g. converts rm to rm -i to prevent you from just deleting stuff without first confirming.

6
  • Quoting from the bash alias man page: There is no mechanism for using arguments in the replacement text.
    – thiton
    Dec 13, 2011 at 14:37
  • That same page also gives the example: $ alias rm='rm -i'
    – Gigi
    Dec 13, 2011 at 14:41
  • 1
    Which is good enough, because it doesn't use any of the arguments of rm, but introduces its own. The problem is that plain aliases can't determine if '-rf *' follows the rm
    – thiton
    Dec 13, 2011 at 14:42
  • You make a valid point.
    – Gigi
    Dec 13, 2011 at 14:45
  • 3
    This will prevent rm -r, but not rm -rf. -f overrides -i.
    – Daniel Beck
    Dec 14, 2011 at 18:26
1

Everyone else is suggesting aliasing rm to rm -i. This is normally a good solution. The trouble is, it won't work in your case. You always use -rf after rm. Your command will become rm -i -rf *, and since the -f comes after the -i, it will override the -i.

You could write a wrapper that checks for -rf and prompts you before executing rm.

1

While this may seem like a strange solution, I've occasionally aliased rm to a script that actually moves to a trash directory instead of removing. If you use the full path to rm you can still empty out that folder, but it solved the "What do you mean rm is permanent?" problem that I get with a lot of recent command line initiates.

0

set up an alias for rm to go through a custom script of yours. It can check the command arguments (-rf *) and print an obnoxious prompt "ARE YOU FLIPPING SURE!?" otherwise it passes it through silently to /usr/bin/rm or whatever.

2
  • 4
    The custom script will never see the '*' because it has been expanded before.
    – thiton
    Dec 13, 2011 at 14:36
  • Damn, you're right. I forgot that when I alias things like that I force the user to enter * as "*"
    – TheCapn
    Dec 13, 2011 at 15:11
0

This is not as easy as it seems, because the '*' is quickly expanded into a file/directory list. The alias rm=rm -i alias is probably the safest bet.

0

tcsh, if you set rmstar, will ask for confirmation any time you invoke rm with a * argument.

Of course that requires using tcsh as your interactive shell; if you're already using bash, that's probably not a good enough reason to switch.

0

Gigi sugested 'rm -i' but it will ask you every time you want to delete something.

My suggestion is to use the 'rm -I' - capital i - alias (alias rm=rm -I) quoting the man page:

          *once before removing  more  than  three  files,  or  when
          removing  recursively.  Less intrusive than -i, while still giv‐
          ing protection against most mistakes*
1
  • Have you tried this with typing rm -rf? -f should override this option.
    – Daniel Beck
    Dec 14, 2011 at 18:37
0

My suggestion is to disable rm with this alias:

alias rm='echo "rm is disabled, use trash or /bin/rm instead."'

and to use trash instead of rm.
(The trash command can be found in the trash-cli package on Debian/Ubuntu)

If you don't like trash, you could also create an alias

alias remove='/bin/rm -irv'

and use remove instead of rm.

0

Not an ideal answer, but does exactly what you need in similar environment. To my knowledge, bash does not support this (at least not through shopt).

zsh delivers option to ask for confirmation when it sees rm used with an asterisk (regardless of flags used with this command).

From man zshoptions

RM_STAR_SILENT (-H) <K> <S>

Do not query the user before executing rm * or rm path/*.

RM_STAR_WAIT

If querying the user before executing rm * or rm path/*, first wait ten seconds and ignore anything typed in that time. This avoids the problem of reflexively answering yes to the query when one didn't really mean it. The wait and query can always be avoided by expanding the * in ZLE (with tab).

-1

The problem here is the way bash will treat the * character in the command. Normally, you could, for example, write your own "rm" script that filtered your input, but in this case the shell is going to treat the '*' as a pattern and expand it before handing the arguments off to whatever you write.

In this case, your best and only bet is to put an alias for rm in your .bashrc that will force-prompt your rm commands:

alias rm='rm -i'
2
  • 2
    No. DO NOT DO THIS. If you're on a computer that doesn't have this, you'll be used to it and probably mess stuff up really badly.
    – Wuffers
    Dec 14, 2011 at 2:28
  • 1
    That and it'd won't work, the -f will override the -i.
    – Rob
    Dec 14, 2011 at 15:46
-1

cd into an empty directory first. rm -rf * will then be harmless.

1
  • He wants to block it, not prevent it. Jul 13, 2012 at 18:38

You must log in to answer this question.