Say I have:
>which -a foo
/bin/foo
/usr/bin/foo
I want something like:
>foo
Warning: multiple foo in PATH
... foo gets executed ...
This functionality would have saved me really really lots of time today. I should have guessed this is happening earlier but the problem was unclear to me at the beggining and I started to dig in quite opposite direction.
Well, you can do it, but it is not so easy as you may think.
First, you need to create a function that will check all directories in the PATH, and look there for the command you try to run. Then you need to bind this function to the DEBUG trap of your current shell.
I wrote a small script that does that:
$ cat /tmp/1.sh
check_command()
{
n=0
DIRS=""
for i in $(echo $PATH| tr : " ")
do
if [ -x "$i/$1" ]
then
n=$[n+1]
DIRS="$DIRS $i"
fi
done
if [ "$n" -gt 1 ]
then
echo "Warning: there are multiple commands in different PATH directories: "$DIRS
fi
}
preexec () {
check_command $1
}
preexec_invoke_exec () {
[ -n "$COMP_LINE" ] && return # do nothing if completing
local this_command=`history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//g"`;
preexec "$this_command"
}
trap 'preexec_invoke_exec' DEBUG
Example of usage:
$ . /tmp/1.sh
$ sudo cp /bin/date /usr/bin/test_it
$ sudo cp /bin/date /bin/test_it
$ test_it
Warning: there are multiple commands in different PATH directories: /usr/bin /bin
Wed Jul 11 15:14:43 CEST 2012
$
It is possible, though a bit trick to generalise. See my answer to https://unix.stackexchange.com/q/42579/20437 for the history
and PROMPT_COMMAND
magic. Your checkSanity function would look something like this:
checkSanity() {
cmd="${1%% *}" # strip everything but the first word
candidates=$(which -a $cmd | wc -l)
if (( candidates > 1 )); then
echo "Warning: multiple $cmd in PATH"
fi
}
But that will print the warning after the command finishes, not at the start. Use the DEBUG trap instead to get the wanted result:
trap 'checkSanity "$BASH_COMMAND"' DEBUG
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With