Bash

關於函式的調試消息

  • April 16, 2021

我需要一個函式來顯示,僅在調試期間,一條消息(函式名稱):

#!/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我得到正確的行為,但還有其他選擇嗎?

謝謝

echo "${FUNCNAME[1]}"列印到標準輸出,因此它的輸出屬於 . 的輸出,而 .debug_function的輸出又屬於test_function.

將消息列印到 stderr:

  • 通過重定向輸出echo
echo "${FUNCNAME[1]}" >&2
  • 或通過在呼叫時重定向debug_function(如果整個函式應僅列印到 stderr)的整個輸出debug_function
debug_function >&2

後一種方法允許內部的命令debug_function直接列印到標準輸出。他們列印的內容將被重定向,因為標準輸出debug_function被重定向。

該函式本身可以將其標準輸出重定向到其標準錯誤exec >&2。這將影響函式中的所有命令。但這也會影響呼叫函式/腳本,除非重定向函式在子 shell 中執行。

您可以使用(debug_function). 要始終在子 shell 中執行函式,請在定義函式時使用()而不是。{}

因此,其全部目的是列印到 stderr 而不是 stdout 的函式可以定義為:

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

現在echo和函式中的其他命令不需要>&2. 即使您簡單地呼叫函式 as debug_function,其中的命令也會列印到 stderr。

注意:一個子shell 或命令的stdout 或stderr 可以不同於另一個子shell 或命令或整個腳本的stdout 或stderr。在許多級別上都可以進行重定向。因此exec >&2,如果“正確”重定向發生在函式體之外,即使是在其自己的子 shell 中執行的函式最終也可以寫入整個腳本的標準輸出。我不會詳細說明。

要記住的最重要的事情:

Stdout 經常被擷取(就像你的情況一樣)或進一步傳輸。stderr 的要點是不要讓錯誤/調試/診斷消息污染 stdout

引用自:https://unix.stackexchange.com/questions/645360