在Bash中等效__FILE__和__LINE__

use*_*507 32 error-handling bash environment-variables

bash中是否包含执行的.sh文件的名称?行号也很棒.

我想在错误消息中使用它,例如:

echo "ERROR: [$FILE:L$LINE] $somefile not found"
Run Code Online (Sandbox Code Playgroud)

ezp*_*zpz 30

#!/bin/bash

echo $LINENO
echo `basename $0`
Run Code Online (Sandbox Code Playgroud)

$LINENO对于$0当前文件的当前行号 .我曾经basename确保你只获得文件名而不是路径.

更新:

#!/bin/bash

MY_NAME=`basename $0`

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

ouch $LINENO
Run Code Online (Sandbox Code Playgroud)

如果使用函数方法,则必须将该行作为参数传递,否则您将获得函数定义的行.

  • `basename $ 0`(不需要'echo`) (4认同)
  • 请注意,如果您'source`脚本,`basename $ 0`将返回父脚本. (4认同)
  • 而且这在脚本加载的登录shell(〜/ .bashrc,/ etc/profile.d/*)中也不能正常工作."BASH_SOURCE"和"BASH_LINENO"要好得多,尽管它们是基础. (2认同)

Kev*_*tle 23

我发现"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"
Run Code Online (Sandbox Code Playgroud)

调用xx产生

2010-06-16.15:33:13.069 xx[11]: here
2010-06-16.15:33:13.073 xx[14]: and here
Run Code Online (Sandbox Code Playgroud)


Lox*_*ley 6

你只需要

echo $LINENO
echo $(basename $0)
Run Code Online (Sandbox Code Playgroud)


Tom*_*ale 5

以下是如何在可重用函数中执行此操作。如果以下内容在名为 的文件中script

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

这会产生输出:

script:main[5]    
Run Code Online (Sandbox Code Playgroud)

这表示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
}
Run Code Online (Sandbox Code Playgroud)