当“functrace”打开时,在 shell 函数执行之前,调试信号的陷阱被触发两次

当“functrace”打开时,在 shell 函数执行之前,调试信号的陷阱被触发两次

我的目标是在执行每个用户定义的函数之前做一些事情。我想到的最直接的方法是使用 trap 来调试信号。

试点脚本运行得很好:

#! /bin/env bash

function welcome { echo "Welcome :)"; }

trap 'declare -F ${BASH_COMMAND%% *} >/dev/null && \
      echo "[Running] ${BASH_COMMAND%% *}"' DEBUG

welcome
## will output:
# [Running] welcome
# Welcome :)

由于我想捕获每个用户定义的函数,因此应打开“functrace”选项。然而,一旦“functrace”打开,陷阱似乎会被触发两次。例如:

#! /bin/env bash
set -o functrace

function welcome { echo "Welcome :)"; }

trap 'declare -F ${BASH_COMMAND%% *} >/dev/null && \
      echo "[Running] ${BASH_COMMAND%% *}"' DEBUG

welcome
## will output:
# [Running] welcome
# [Running] welcome
# Welcome :)

那么,我的脚本或 bash 有什么问题吗?如何区分这两种召唤?

答案1

我也刚刚遇到这个问题。很难确切地说发生了什么,但似乎第二次调用是在被调用函数的上下文中触发的,所以你可以这样做:

! /bin/env bash
set -o functrace

function welcome { echo "Welcome :)"; }


function __debug_trap {
  declare -F ${BASH_COMMAND%% *} >/dev/null
  # funcname[0] is __debug_trap; funcname[1] is the next function on stack
  if ! [[ "${BASH_COMMAND%% *}" == "${FUNCNAME[1]}" ]]; then
    echo "[Running] ${BASH_COMMAND%% *}"
  fi
}

trap __debug_trap DEBUG

welcome
echo not in function

#bash test.sh
#[Running] welcome
#[Running] echo
#Welcome :)
#[Running] echo
#not in function

剩下的主要问题是,这将错误地抑制直接递归调用;但这些在 bash 中并不常见。

相关内容