Tip: the bash builtin "type" command for functions

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
2 Likes

Welcome!
We hope you find our forum helpful and friendly, and we thank you for sharing

All the best

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
)

I have prefixed a "Tip:" to the title.

3 Likes

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
)
2 Likes

This topic was automatically closed 300 days after the last reply. New replies are no longer allowed.