Sample Header Ad - 728x90

Get Length of Function in Shell

3 votes
2 answers
401 views
**UPDATE:** **Some Background:** zsh returns the line number inside a function when $LINENO is called inside a function. I need a way to get the line number in the file and to differentiate when zsh is giving me a file line number vs. a function line number. I couldn't find a zsh environment variable to change this behavior to match other Bourne shells (e.g. bash always gives the file line number), so I was trying to see if I could create a function with logic that could always output the file line number regardless of context. This is why I was trying to determine the length of the function. If anyone knows of a good way to get the file line number with $LINENO in zsh in all contexts, I'd appreciate it! --- **QUESTION:** I've searched this and this , but can't seem to find an answer. Is there a portable way to write the number of lines a function definition has? *(Please see "Some Background" above.)* My initial thought was to capture the function contents and pipe it to wc -l. Consider the following test file: **Test File:**
sh
#! /bin/sh
#
# test_file.sh

func1() { echo 'A one-liner'; }  # With a nasty comment at the end
func2 (){
  echo "A sneaky } included"
  # Or an actual code block
  {
    echo 'hi'
    echo 'there'
  }
}

func3() { echo "I'm on a line."; }; echo 'And so am I'

func4(){ echo "But I'm a \"stand-alone\" one-liner."; }

func5() {
  echo "I'm a nice function."
  echo "And you can too!"


}

echo "Can we do this?"
My initial attempt was to match corresponding pairs of {}'s with sed: **Solution Attempt:**
sh
#! /bin/sh
#
# function_length
#
# $1: string: absolute path to file
# $2: string: name of function (without ()'s)

fp=$(realpath "$1")
func_name="$2"

func_contents=$(cat "${fp}" |
  sed -E -n '
/'"${func_name}"' ?[(][)]/{
  :top
  /[}]/!{
    H
    d
  }
  /[}]/{
    x
    s/[{]//
    t next
    G
    b end
  }
  :next
  x
  b top
  :end
  p
  q
}')

echo "${func_contents}"
echo

func_len=$(echo "${func_contents}" | wc -l)

echo "Function Length: ${func_len}"
However, running this in zsh gives
sh
$ ./function_length ./test_file.sh func1      

func1() { echo 'A one-liner'; }  # With a nasty comment at the end

Function Length: 2
$ ./function_length ./test_file.sh func2


Function Length: 1
$ ./function_length ./test_file.sh func3

func3() { echo "I'm on a line."; }; echo 'And so am I'

Function Length: 2
$ ./function_length ./test_file.sh func4

func4(){ echo "But I'm a \"stand-alone\" one-liner."; }

Function Length: 2
$ ./function_length ./test_file.sh func5


Function Length: 1
Does anyone know of a solution? Thank you!
Asked by adam.hendry (243 rep)
Jun 13, 2021, 09:13 PM
Last activity: Jun 28, 2025, 01:30 PM