Контекст вызывающего функции в ZSH: эквивалент Bash `Caller`

Сценарий запускается в подоболочке, любые изменения среды (каталог и переменные) являются локальными для этого процесса и возвращаются к изменениям вызывающего процесса, когда процесс завершается (или иначе возвращает управление обратно).

Вы можете запускать команды в текущей оболочке (чтобы их действие сохранялось), используя исходный код сценария (. Здесь / is / the / script ) или определяя функцию оболочки. Функции оболочки могут быть довольно сложными и, что особенно важно, выполняются в текущем процессе оболочки. Не все оболочки поддерживают функции (bash поддерживает).

8
03.07.2018, 10:31
1 ответ

Основываясь на ответе муру , я реализовал следующую функцию, которая работает в обоих{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
3
27.01.2020, 20:10

Теги

Похожие вопросы