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:
#! /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:
#! /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
$ ./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!
zsh
returns the line number inside a function when$LINENO
is called and I needed a way to get the line number in the file. I couldn't find an environment variable to change this behavior to match other Bourne shells (bash, e.g.), so I was trying to see if I could create a function with logic that could output the file line number. I'll update my question. – adam.hendry Jun 15 '21 at 15:16