如何编写可识别是否在复合命令中被调用的Shell函数
实现Shell函数判断是否为单独调用的方案
要让magic_function仅在单独执行时(比如magic_function;)执行history -s操作,在复合命令、函数内调用等场景下跳过,可以采用以下实现方式:
实现代码
magic_function() { # 被其他函数调用时直接返回 if (( ${#FUNCNAME[@]} > 1 )); then echo "函数内调用,跳过history操作" return fi # 获取最近一条执行的命令,清理行号和多余空白字符 local last_cmd last_cmd=$(history 1 | sed 's/^[0-9]*\s*//' | xargs) # 判断是否为单独调用本函数 if [[ "$last_cmd" == "magic_function" || "$last_cmd" == "magic_function;" ]]; then echo "单独调用,执行history操作" history -s "your_custom_history_entry" # 替换为你需要添加的历史记录内容 else echo "复合命令中调用,跳过history操作" fi }
关键逻辑解析
- 函数调用栈检测:
FUNCNAME是Bash内置数组,存储当前调用栈的函数名。当数组长度大于1时,说明当前函数被其他函数调用,直接跳过特殊操作。 - 命令行内容校验:通过
history 1获取最近执行的命令行,用sed去除行号,xargs清理首尾空白和中间冗余空格,再对比是否仅为magic_function或带分号的调用形式,以此判断是否为单独执行。 - 复合场景覆盖:无论是多命令串联(
date; magic_function; uptime)、循环内调用还是其他复合结构,history 1获取的命令都会包含额外内容,从而触发跳过逻辑。
测试用例验证
- 单独调用:执行
magic_function或magic_function;,会执行history -s操作。 - 函数内调用:在自定义函数(如
funky)里调用magic_function,会跳过操作。 - 复合命令:执行
date && magic_function或for i in {1..2}; do magic_function; done,会跳过操作。
内容的提问来源于stack exchange,提问作者lordadmira
相关产品推荐
相关产品推荐

