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 string command rm ...
runs the external rm
command, avoiding recursion back to our function again. Since you can't know if there is a wildcard, why not check the number of arguments?
For example:
#!/bin/bash
rm () {
if [ "$#" -gt 1 ]; then
echo command rm -i "$@"
else
echo command rm "$@"
fi
}
rm a b c
rm a
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.