type -a somename is great for finding if somename is an executable (path program, function, alias, or bash builting or keyword. The is very useful when naming a new script with a unique executable name. But if somename is a function, type only shows the code, not where the function is declared.
This little script (I call it typ2) overcomes that. NOTE, it runs interactively (-i in the shebang) so that it launches in a login shell, i.e.: contains the login environment loaded.
#!/usr/bin/bash -i
#In case the login script has an EXIT trap, turn it off
trap "" EXIT
# type2 Requires a SINGLE arg (command name, no path); other args ignored.
ARG=$(basename $1 2>/dev/null)
if [ ! $ARG ];then
echo "A *single* parameter (command name) is required."
exit
fi
if [[ ! $(type -a $ARG 2>/dev/null ) ]]; then
echo "$ARG is not a function, alias, keyword, builtin or PATH command."
exit
else
type -a $ARG
fi
#IF FUNCTION, show location:
if [ $(type -t $ARG | grep "function") ]; then
shopt -s extdebug
TMP=$(declare -F $ARG)
LINE=$(echo $TMP | grep -o '[0-9]\+')
echo -n "$ARG is declared on Line $LINE in: "
echo $TMP | sed 's/.* \//\//'
shopt -u extdebug
fi
Nice!
And thanks for showing me the extdebug option!
I suggest to shorten it:
#!/bin/bash -i
# type2
# You can include(source) this to also find current (not saved) aliases and functions.
(
# A subshell won't leave variables and settings behind
for arg
do
if tmpx=$( type -a "$arg" 2>/dev/null )
then
echo "$tmpx"
else
echo "$arg is not a function, alias, keyword, builtin or PATH command."
fi
if tmpx=$( shopt -s extdebug; declare -F "$arg" 2>/dev/null )
then
read arg line tmpx <<< "$tmpx"
echo "$arg is declared on Line $line in: $tmpx"
fi
done
)
Great streamlining! Thanks. And thanks for adding "Tip:"
I've added another thing -- a test for VARIABLE using set:
#!/bin/bash -i
# type2
# You can include(source) this to also find current (not saved) aliases and functions.
(
# A subshell won't leave variables and settings behind
for arg
do
if tmpx=$( type -a "$arg" 2>/dev/null )
then
echo "$tmpx"
elif tmpx=$( set | grep -e "^$arg=" )
then
echo "$arg is a variable: $tmpx"
else
echo "$arg is not a function, alias, keyword, builtin, variable, or PATH command."
fi
if tmpx=$( shopt -s extdebug; declare -F "$arg" 2>/dev/null )
then
read arg line tmpx <<< "$tmpx"
echo "$arg is declared on Line $line in: $tmpx"
fi
done
)