我的目标是在执行每个用户定义的函数之前做一些事情。我想到的最直接的方法是使用 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 中并不常见。