Эквивалент __FILE__ и __LINE__ в Bash - PullRequest
28 голосов
/ 16 июня 2010

Есть ли в bash переменная, которая содержит имя исполняемого файла .sh? Номер строки тоже был бы отличным.

Я хочу использовать его в сообщениях об ошибках, таких как:

echo "ERROR: [$FILE:L$LINE] $somefile not found"

Ответы [ 4 ]

26 голосов
/ 16 июня 2010
#!/bin/bash

echo $LINENO
echo `basename $0`

$LINENO для текущего номера строки $0 для текущего файла.Я использовал basename, чтобы убедиться, что вы получаете только имя файла, а не путь.

ОБНОВЛЕНИЕ:

#!/bin/bash

MY_NAME=`basename $0`

function ouch {
   echo "Fail @ [${MY_NAME}:${1}]"
   exit 1
}

ouch $LINENO

Вы должны передать строку в качестве параметра, если вы используете подход функциииначе вы получите строку определения функции.

20 голосов
/ 16 июня 2010

Я считаю полезными встроенные массивы "BASH_SOURCE" и "BASH_LINENO":

$ cat xx
#!/bin/bash

_ERR_HDR_FMT="%.23s %s[%s]: "
_ERR_MSG_FMT="${_ERR_HDR_FMT}%s\n"

error_msg() {
  printf "$_ERR_MSG_FMT" $(date +%F.%T.%N) ${BASH_SOURCE[1]##*/} ${BASH_LINENO[0]} "${@}"
}

error_msg "here"


error_msg "and here"

Вызов хх доходности

2010-06-16.15:33:13.069 xx[11]: here
2010-06-16.15:33:13.073 xx[14]: and here
6 голосов
/ 16 июня 2010

Вам просто нужно

echo $LINENO
echo $(basename $0)
2 голосов
/ 03 июля 2018

Вот как это сделать в многократно используемой функции.если следующее находится в файле с именем script:

#!/bin/bash
debug() {
  echo "${BASH_SOURCE[1]##*/}:${FUNCNAME[1]}[${BASH_LINENO[0]}]" > /dev/tty
}
debug

Это приводит к выводу:

script:main[5]    

, который указывает строку, на которой был вызван debug.


Далее будут распечатаны имя файла, функция, строка и необязательное сообщение.

Также работает в 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
}
...