How can I block execution of rm -rf * in a Linux shell?

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?

user1095939

Posted 2011-12-13T14:31:06.347

Reputation:

11Don't sleep and code? – None – 2011-12-13T14:33:37.190

12Break the habit rather than seek a technological solution. It's still and counter productive. – Noufal Ibrahim – 2011-12-13T14:35:18.997

7You seem to be searching technical solutions for psychological problems. Always try to solve a problem within its solution domain. – thiton – 2011-12-13T14:39:08.383

I second this, if you ever ssh into my box you might accidentally kill everything. NO GOOD! – reconbot – 2011-12-13T20:56:17.717

Answers

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

Shawn Chin

Posted 2011-12-13T14:31:06.347

Reputation: 1 174

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.

Gigi

Posted 2011-12-13T14:31:06.347

Reputation: 141

Quoting from the bash alias man page: There is no mechanism for using arguments in the replacement text. – thiton – 2011-12-13T14:37:03.797

That same page also gives the example: $ alias rm='rm -i' – None – 2011-12-13T14:41:41.997

1Which 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 – 2011-12-13T14:42:56.383

You make a valid point. – None – 2011-12-13T14:45:49.357

3This will prevent rm -r, but not rm -rf. -f overrides -i. – Daniel Beck – 2011-12-14T18:26:54.790

@DanielBeck: One could write a wrapper around rm which would do the argument parsing. – Benjamin Bannier – 2011-12-14T19:23:38.637

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.

Jonathan

Posted 2011-12-13T14:31:06.347

Reputation: 291

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.

Jason Ritzke

Posted 2011-12-13T14:31:06.347

Reputation: 11

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

styrofoam fly

Posted 2011-12-13T14:31:06.347

Reputation: 1 746

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.

Grambot

Posted 2011-12-13T14:31:06.347

Reputation: 227

4The custom script will never see the '*' because it has been expanded before. – thiton – 2011-12-13T14:36:24.453

Damn, you're right. I forgot that when I alias things like that I force the user to enter * as "*" – None – 2011-12-13T15:11:33.610

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.

thiton

Posted 2011-12-13T14:31:06.347

Reputation: 826

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.

Keith Thompson

Posted 2011-12-13T14:31:06.347

Reputation: 4 645

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*

Grasiani

Posted 2011-12-13T14:31:06.347

Reputation: 1

Have you tried this with typing rm -rf? -f should override this option. – Daniel Beck – 2011-12-14T18:37:48.440

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.

Dario Seidl

Posted 2011-12-13T14:31:06.347

Reputation: 2 409

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

Christopher Neylan

Posted 2011-12-13T14:31:06.347

Reputation: 701

2No. *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 – 2011-12-14T02:28:50.303

1That and it'd won't work, the -f will override the -i. – Rob – 2011-12-14T15:46:14.303

-1

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

Richard Kettlewell

Posted 2011-12-13T14:31:06.347

Reputation: 756

He wants to block it, not prevent it. – Tamara Wijsman – 2012-07-13T18:38:26.280