-1

Is there any way to completely prevent this command from being executed, by mistake, in the terminal? I know that bash, for instance, has aliases. Is there a way to use them?

  • 1
    Don't. Have a backup ready. See the comment below this answer to a similar question. – pLumo Dec 7 '18 at 14:16
  • 2
    short answer you cannot. – Kiwy Dec 7 '18 at 14:55
  • long answer you could do this superuser.com/a/1220510/264697 – Kiwy Dec 7 '18 at 14:55
  • Only that specific command, or removing files in general? Or files under your home directory? – Jeff Schaller Dec 7 '18 at 15:16
5

Yes, there are many ways to avoid rm doing a mess. But, instead of making rm and similar commands foolproof, it would be better if you just learn to use your Unix system responsibly.

My advices:

  • Be extremely careful when dealing with dangerous commands (rm, dd, shred, eval, etc).

  • Don't execute anything unless you are completely sure you haven't mistyped something.

  • If you don't completely understand a given command, don't execute it. Go read its manual before proceeding.

  • Make backups. And make backups of your backups.


That said, you could do something like this:

alias rm='rm -i'
rm() { command rm -i "${@}"; }

It wouldn't protect you if you pass the -f option, but it works for simple cases:

$ rm file
rm: remove regular file 'file'? y

Or you could write a more complex wrapper.

The biggest issue with this approach is that you may get used to this non-standard behavior, which could be really dangerous if you need to work on a system where there's no such alias/function/wrapper.

  • 6
    The biggest issue with this approach is that you may get used to this non-standard behavior Exactly. That's why such "protections" are actually very dangerous. And you left off, "Don't use the root account or sudo except as absolutely necessary, and logout of root immediately when you're done with whatever you need to use root for." – Andrew Henle Dec 7 '18 at 15:12
  • 3
    The biggest issue with this approach is that it doesn't really work, you end up typing "y" as a reflex without checking the file name. It is also a huge pain in the behind when you have to erase a whole tree of files. – xenoid Dec 7 '18 at 15:18
  • +1 for not just giving advice, but actually answering question as well! – FreeSoftwareServers Dec 7 '18 at 21:19
2

Exactly as asked, this wrapper function would prevent one particular kind of mistake for that user:

function rm {
  if [ "$#" -eq 2 ] && [ "$1" = "-rf" ] && [ "$2" = "$HOME" ]
  then
    echo Avoiding a dangerous command...
    return
  else
    command rm "$@"
  fi
}

... since bash would replace rm -rf ~ with rm -rf $HOME, if $HOME is set (the user's home directory otherwise).

This would not prevent very many mistakes, though. You could broaden the test to loop through the parameters and check each one for being a subset of $HOME, or whatever you're trying to be careful with.

This won't protect the user from executing rm -rf ./* or \rm -rf ~ or sudo rm -rf ~ or a whole host of other variations.

1

A trick that you can use: remove the read permission on the directory you want to protect. This prevents explicitly or implicitly listing the directory contents, which is necessarily done by any command to which you don't provide specific children files or directories. When you specify the names of the children you only need directory traversal rights (the execute flags) so you can still access everything below the protected directory.

A quick demo:

# Create the directory, remove its 'read' flag
**$ mkdir protected && chmod -r protected && ls -ald protected
d-wx--x--x 2 me me 4096 Dec  7 21:58 protected

# You cannot list contents since you cannot read it
**$ ls protected
ls: cannot open directory 'protected': Permission denied

# You can create files in it since you have write permission
**$ touch protected/{1..3}

# You can list specific directories entries
**$ ls -al protected/1
-rw-r--r-- 1 me me 0 Dec  7 21:59 protected/1

# You can also create subdirectories
**$ mkdir protected/subdir

# ... and create files in them
**$ touch protected/subdir/{1..3}

# ... do wilcard listing of these subdirectories
**$ ls -al protected/subdir
total 8
drwxr-xr-x 2 me me 4096 Dec  7 21:59 .
d-wx--x--x 3 me me 4096 Dec  7 21:59 ..
-rw-r--r-- 1 me me    0 Dec  7 21:59 1
-rw-r--r-- 1 me me    0 Dec  7 21:59 2
-rw-r--r-- 1 me me    0 Dec  7 21:59 3

# You can erase files, along as you specify them explicitly
**$ rm protected/{1..3}

# You cannot do a blanket erase, since it would require reading the directory
**$ rm -rf protected
rm: cannot remove 'protected': Permission denied

# ... but that works on its subdirectories
**$ rm -rf protected/subdir

# You can still remove the directory once it is empty
**$ rmdir protected

But I doubt this solution is workable on a home directory, since there are likely many utilities around that assume read rights (your file explorer, for instance).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.