函数上的调试消息

函数上的调试消息

我需要一个函数来仅在调试期间显示一条消息(函数名称):

#!/bin/bash

debug_function(){
  if [[ $DEBUG -eq 1 ]]; then
    echo "${FUNCNAME[1]}"
  else
    DEBUG=0
  fi
}

test_function(){
 debug_function
 echo "something"
}

foo=$(test_function)

echo "Result: $foo"

它可以工作,但在 DEBUG=1 中,函数名称显然会添加到函数输出中。

# sh test
Result: something

# DEBUG=1 sh test
Result: test_function
something

有没有办法只打印一条消息?

使用wall我得到了正确的行为,但是还有其他选择吗?

谢谢

答案1

echo "${FUNCNAME[1]}"打印到 stdout,因此它的输出属于 的输出debug_function,而后者又属于 的输出test_function

将消息打印到 stderr:

  • 通过重定向输出echo

    echo "${FUNCNAME[1]}" >&2
    
  • 或者在调用时重定向整个输出debug_function(如果整个函数应该只打印到 stderr)debug_function

    debug_function >&2
    

后一种方法允许将内部命令debug_function直接打印到标准输出。它们打印的内容将被重定向,因为 stdoutdebug_function被重定向。

函数本身可以将其 stdout 重定向到其 stderr exec >&2。这将影响函数中的所有命令。但这也会影响调用函数/脚本,除非重定向函数在子 shell 中运行。

您可以根据需要在子 shell 中运行该函数(debug_function)。要始终在子 shell 中运行该函数,请在定义该函数时使用()而不是。{}

因此,一个其全部目的是打印到 stderr 而不是 stdout 的函数可以定义如下:

debug_function()(
   exec >&2
   echo whatever
   # ...
)

Nowecho和函数中的其他命令不需要>&2.即使您简单地调用该函数debug_function,其中的命令也会打印到 stderr。

注意:一个子 shell 或命令的 stdout 或 stderr 可能与另一子 shell 或命令或整个脚本的 stdout 或 stderr 不同。重定向可以在许多级别上实现。因此,如果“正确”的重定向发生在函数体之外,即使是在自己的子 shell 中执行的函数exec >&2最终也可以写入整个脚本的 stdout。我就不详细说了。

最重要的是要记住:

标准输出通常会被捕获(就像您的情况一样)或进一步通过管道传送。 stderr 的要点是不要让错误/调试/诊断消息污染标准输出

相关内容