Bash에서는 다음과 같이 작성할 수 있습니다.
caller 0
그리고 받았다방문객상황별:
- 전화 번호
- 기능
- 스크립트 이름
이는 디버깅에 매우 유용합니다. 반면:
yelp () { caller 0; }
yelp
그런 다음 어떤 코드 줄에 도달했는지 확인하기 위해 글을 쓸 수 있습니다 .
caller 0
다음 과 같이 구현할 수 있습니다 bash
.
echo "${BASH_LINENO[0]} ${FUNCNAME[1]} ${BASH_SOURCE[1]"
caller 0
에서와 동일한 출력을 어떻게 얻을 수 있습니까 zsh
?
답변1
내장은 없는 것 같아요주문하다동일하지만 이 네 가지 변수의 일부 조합zsh/매개변수 모듈다음을 사용할 수 있습니다:
funcfiletrace
EVAL_LINENO
이 배열에는 현재 함수, 소스 파일 또는 (설정된 경우) 명령이 호출된 위치의 절대 행 번호와 해당 파일 이름이 포함됩니다eval
. 이 배열은funcsourcetrace
및 와 길이는 동일functrace
하지만funcsourcetrace
라인과 파일이 정의 지점이 아닌 호출 지점이라는 점이 다르며functrace
모든 값이 함수 시작에 상대적인 것이 아니라 파일의 절대 라인 번호라는 점에서 다릅니다( 있습니다).funcsourcetrace
이 배열에는 현재 실행 중인 함수, 소스 파일 및 (설정된 경우) 명령을 정의하는 지점의 파일 이름과 줄 번호가 포함됩니다
EVAL_LINENO
. 줄 번호는 " " 또는 " "로 시작하는 줄입니다. 자동 로드된 함수의 경우 행 번호는 0으로 보고됩니다. 각 요소의 형식은 다음과 같습니다.eval
function name
name ()
filename:lineno
기본 zsh 형식(파일에 함수 본문만 표시됨)의 파일에서 자동 로드되는 함수 또는 내장 함수
source
또는 ' '에 의해 실행된 파일의 경우 추적 정보가 표시됩니다. 정의되어 있습니다. 함수를 로드할 때 소스 파일 이름은 절대 경로로 확인되고, 그렇지 않으면 해당 경로가 확인됩니다..
filename:0
대부분의 사용자는 배열의 정보에 관심이 있을 것입니다
funcfiletrace
.funcstack
배열에는 함수 이름, 소스 파일 및 (
EVAL_LINENO
설정된 경우)eval
명령이 포함됩니다. 현재 실행 중입니다. 첫 번째 요소는 이 매개변수를 사용하는 함수의 이름입니다.표준 쉘 배열을
zsh_eval_context
사용하여 각 깊이에서 실행되는 쉘 구성의 유형을 결정할 수 있습니다. 그러나 순서가 반대이므로 마지막 항목이 가장 최근 항목이고 더 자세한 항목입니다(예: 최상위 항목 포함). 메인 셸 코드를 대화식으로 실행하거나 스크립트에서 실행하는 경우$funcstack
.functrace
이 배열에는 현재 실행 중인 함수에 해당하는 호출자의 이름과 줄 번호가 포함됩니다. 각 요소의 형식은 입니다
name:lineno
. 또한 소스 파일의 호출자는source
또는 ' ' 명령이 실행되는 지점입니다..
비교하다:
foo.bash
:
#! /bin/bash
yelp() {
caller 0
}
foo () {
yelp
}
foo
foo.zsh
:
#! /bin/zsh
yelp() {
print -l -- $funcfiletrace - $funcsourcetrace - $funcstack - $functrace
}
foo () {
yelp
}
foo
결과:
$ bash foo.bash
7 foo foo.bash
$ zsh foo.zsh
foo.zsh:7
foo.zsh:10
-
foo.zsh:2
foo.zsh:6
-
yelp
foo
-
foo:1
foo.zsh:10
따라서 해당 값은 ${funcfiletrace[1]}
및 에 있습니다 ${funcstack[-1]}
. 로 변경 yelp
:
yelp() {
print -- $funcfiletrace[1] $funcstack[-1]
}
출력은 다음과 같습니다
foo.zsh:7 foo
이것은 bash에 매우 가깝습니다.
7 foo foo.bash
답변2
기반으로무루의 대답, 두 가지 모두에서 작동하는 다음 기능을 구현했습니다 {ba,z}sh
.
$ cat yelp
#!/bin/zsh
# Say the file, line number and optional message for debugging
# Inspired by bash's `caller` builtin
# Thanks to https://unix.stackexchange.com/a/453153/143394
function yelp () {
# shellcheck disable=SC2154 # undeclared zsh variables in bash
if [[ $BASH_VERSION ]]; then
local file=${BASH_SOURCE[1]} func=${FUNCNAME[1]} line=${BASH_LINENO[0]}
else # zsh
emulate -L zsh # because we may be sourced by zsh `emulate bash -c`
# $funcfiletrace has format: file:line
local file=${funcfiletrace[1]%:*} line=${funcfiletrace[1]##*:}
local func=${funcstack[2]}
[[ $func =~ / ]] && func=source # $func may be filename. Use bash behaviour
fi
echo "${file##*/}:$func:$line $*" > /dev/tty
}
foo () { yelp; }
yelp
foo
출력은 다음과 같습니다
$ ./yelp
yelp::20
yelp:foo:19