I want to have bash run rm -i *
if I type rm *
but otherwise run regular rm
. Importantly, I don't want to run rm -i
every time I use a wildcard such as rm part*
. Here is as far as I could come up with:
rm ()
{
if [ "$1" == "*" ]; then
rm -i *
else
rm $1
fi
}
But I know this will fail. I know that the comparison I want is to ^*$
, but I don't know how to implement it.
It's literally impossible to know if your command was called with a wildcard without the cooperation of your shell.
When you invoke rm *
(like any other command), the *
is replaced with a list of filenames before invocation. Thus, when inside the command, the information that it was given a wildcard no longer exists: $1
, $2
, etc. have been replaced with a list of names that the wildcard expanded to.
That said, since we're a shell function, the cooperation of our shell is actually available:
rm() {
local cmd
read -r _ cmd < <(HISTTIMEFORMAT=''; history 1)
if [[ $cmd = "rm *" ]]; then
command rm -i "$@"
else
command rm "$@"
fi
}
How does this work?
history 1
returns the most recent command in the shell's history (preceded by a number).read -r _ cmd
reads that number into the variable _
, and the rest of the command line into the variable cmd
[[ $cmd = "rm *" ]]
compares the command against that precise stringcommand rm ...
runs the external rm
command, avoiding recursion back to our function again.