Shell에서 함수 길이 얻기

Shell에서 함수 길이 얻기

고쳐 쓰다:

일부 배경:

zsh$LINENO함수 내부에서 호출되면 함수 내부의 줄 번호를 반환합니다. 파일의 줄 번호를 가져오고 zsh파일 줄 번호와 함수 줄 번호가 주어졌을 때 이를 구별하는 방법이 필요합니다.

zsh다른 Bourne 쉘과 일치하도록 이 동작을 변경하는 환경 변수를 찾을 수 없었기 때문에 (예: bash항상 파일 줄 번호 제공) 항상 파일 줄의 컨텍스트를 출력하는 논리를 사용하여 함수를 만들 수 있는지 확인하려고 했습니다. 숫자. 그래서 함수의 길이를 결정하려고 합니다.

$LINENO모든 상황에서 파일의 줄 번호를 얻는 좋은 방법을 아는 사람이 있다면 zsh감사하겠습니다!


질문:

나는 검색했다이것그리고이것, 하지만 답을 찾을 수 없는 것 같습니다. 함수 정의를 한 줄로 작성하는 이식 가능한 방법이 있나요?(위의 "일부 배경"을 참조하십시오.)

내 초기 아이디어는 함수 내용을 캡처하여 wc -l.

다음 테스트 파일을 고려해보세요.

테스트 파일:

#! /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?"

나의 초기 시도는 sed를 사용하여 해당 {} 쌍을 일치시키는 것이었습니다.

시도해 볼 수 있는 해결 방법:

#! /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}"

그러나 zsh에서 실행하면

$ ./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

누구든지 해결책을 알고 있습니까? 감사합니다!

답변1

쉘 함수의 내용을 검색하는 이식 가능한 방법은 없습니다. 일부 껍질에는 있고 일부에는 없습니다. 인기있는 쉘스프린트함수 본문을 평가하는 것 외에는 어떤 작업도 수행할 수 없습니다.

dash/src $ grep -F ndefun.body *.c
eval.c: evaltree(func->n.ndefun.body, flags & EV_TESTED);
parser.c:                               n->ndefun.body = command();

소스 코드를 자세히 조사해 보면 함수의 "길이"가 무엇을 의미하든 포함하는 별도의 데이터 구조가 없음을 알 수 있습니다.

함수 정의를 인쇄하는 방법이 있는 쉘에서는 해당 형식이 소스 코드와 다를 수 있습니다. 따라서 "길이"는 의미 있는 숫자가 아닙니다.

$ bash -c 'f () { echo hello; echo world; }; typeset -f f'
f () 
{ 
    echo hello;
    echo world
}
$ ksh -c 'f () { echo hello; echo world; }; typeset -f f'; echo
f() { echo hello; echo world; };
$ mksh -c 'f () { echo hello; echo world; }; typeset -f f'
f() {
        \echo hello 
        \echo world 
} 
$ zsh -c 'f () { echo hello; echo world; }; typeset -f f'
f () {
        echo hello
        echo world
}

관련 정보