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