Secure rm bash command with wildcard extension check

Sometimes this situation happens: you type on the CLI 'rm * ~' instead of 'rm *~'. The former would delate all the files in your cwd, the later would just do that what you wanted, i.e. cleanup emacs backup files.

That's why I wanted a script which just looks if there is a '*' in the argv of the rm command. Due to the wildcard extension of the bash, this would not work. Instead, the '*' would be extended before passing it to such a script.

But here is the solution using a magic alias. Create a short script (e.g. in python), which parses your argument vector for a lonely '*' pattern. Save this executable script e.g. as ~/bin/rms.py in your private bin-folder.

  
#! /usr/bin/env python
import sys, os
from string import split, join

execute=True
if '*' in sys.argv:
    ok=False
    while not ok:
        print "your rm command contains a '*'. Are you sure? y/[n]"
        answer=sys.stdin.readline()[:-1]
        if (answer == 'y') or (answer == 'Y'):
            execute=True
            ok=True
        elif (answer == 'n') or (answer == 'N') or (answer == ''):
            execute=False
            ok=True            
if execute:
    cmd='/bin/rm'
    for arg in sys.argv[1:]:
	#todo: insert escape char where it is necessary
	if not '*' in arg:
             cmd += ' "'+arg+'"'   #special char handling
        else:
             cmd += ' '+arg        #wildcard extension -- whitespaces and special chars in combination with '*' might be a problem now ... see todo
    #print "executing", cmd
    os.popen(cmd)
else:
    print "noop"

Now create a magic alias for the normal rm command without any wildcard extensions just for this command/script. Put this into your ~/.bashrc file:

  
 noglob_helper() {
     "$@"
     case "$shopts" in
         *noglob*) ;;
         *) set +f ;;
     esac
     unset shopts
 }
 alias noglob='shopts="$SHELLOPTS"; set -f; noglob_helper'
 alias rm='noglob ~/bin/rms.py'           # rm-secure
 alias rmf='/bin/rm'                      # rm-forced

Then do a source ~/.bashrc to reload your file and try a again a 'rm * ~'


Philippe Dreuw
Last modified: Wed Feb 6 10:20:35 CET 2008 Disclaimer. Created Wed Dec 22 18:04:32 CET 2004

Valid HTML 4.01! xemacs logo debian logo