与Bash中的_文件和_行相当

与Bash中的_文件和_行相当,bash,error-handling,environment-variables,Bash,Error Handling,Environment Variables,bash中是否有任何变量包含执行的.sh文件的名称?线路号也会很好 我想在错误消息中使用它,例如: echo "ERROR: [$FILE:L$LINE] $somefile not found" 当前行号的$LINENO 当前文件的$0。我使用basename确保只获取文件名,而不获取路径 更新: #!/bin/bash MY_NAME=`basename $0` function ouch { echo "Fail @ [${MY_NAME}:${1}]" exit 1 }

bash中是否有任何变量包含执行的.sh文件的名称?线路号也会很好

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

echo "ERROR: [$FILE:L$LINE] $somefile not found"
当前行号的
$LINENO
当前文件的
$0
。我使用
basename
确保只获取文件名,而不获取路径

更新:

#!/bin/bash

MY_NAME=`basename $0`

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

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

只需

echo $LINENO
echo $(basename $0)
我发现“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"
调用xx产生

2010-06-16.15:33:13.069 xx[11]: here
2010-06-16.15:33:13.073 xx[14]: and here

下面介绍如何在可重用函数中实现这一点。如果以下内容位于名为
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
}

basename$0
(不需要
echo
)请注意,如果
source
脚本,
basename$0
将返回父脚本。而且,在加载了脚本的登录shell(~/.bashrc,/etc/profile.d/*)中,这也不起作用。“BASH_SOURCE”和“BASH_LINENO”更好,尽管它们是BASH主义。在任何
源代码
d脚本中都会失败。
basename$0
(不需要
echo
),我也更喜欢使用您描述的BASH_*变量。这里有一篇关于如何调试我在过去引用过的bash脚本的好文章:请参阅此处的日志记录和错误处理实现:它涉及使用bash内置的
caller
命令以及
bash\u SOURCE
bash\u LINENO
数组来记录执行/转储堆栈跟踪的上下文非常好的解决方案。虽然我认为必须有一种方法使它更紧凑,但我没有发现它,我喜欢在我的许多生产/关键shell脚本中使用
set-euo pipefail
,所以我稍微修改了它,使用
if[${BASH_VERSION:-}];然后
代替
if[[$BASH_VERSION]];然后
否则我会得到
yelp:3:BASH\u VERSION:parameter not set
,这是预期的,因为
set-u
的严格性,它将在访问未设置的变量时退出
# 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
}