Shell-Script

sh shell:將輸出重定向到終端和腳本內的文件

  • March 25, 2021

如何從腳本內部將 stdout 和 stderr 重定向到文件和終端。

#!/bin/sh

LOG_FILE="/tmp/abc.log"

exec &> >(tee -a $LOG_FILE)

echo "Start"
echo "Hi" 1>&2 
echo "End"

我找到了上面的腳本。但是這個腳本只適用於 bash。使用 sh shell 會出現以下錯誤:

./abc.sh: 5: Syntax error: redirection unexpected (expecting word)

我想要一個同時適用於 sh 和 bash shell 的腳本。

是的,&>是一個bash運算符(現在也支持zsh, 雖然zsh總是有>&相同的 like in csh),和>(...)一個ksh運算符(現在也支持zshand bash),也不是sh運算符。那個不帶引號的 $LOG_FILE 在這裡你顯然不想要 split+glob ,使它成為 zsh 語法(在不帶引號的擴展時不隱式執行 split+glob 的那些 shell 中唯一的一個,儘管在 中zsh,你只是這樣做exec >&1 > $LOG_FILE 2>&1)。

sh語法中,您可以執行以下操作:

#! /bin/sh -
LOG_FILE="/tmp/abc.log"

{

 # your script here


} 2>&1 | tee -- "$LOG_FILE"

或者把所有東西都放在一個函式中:

#! /bin/sh -
LOG_FILE="/tmp/abc.log"

main() {

 # your script here


}

main "$@" 2>&1 | tee -- "$LOG_FILE"

在任何情況下,這種方法和您的zsh-style 方法最終都會在與在標準輸出上打開的相同資源上列印錯誤消息。因此,如果有人這樣做your-script > out 2> errerr將是空的,並且out將包含正常輸出和錯誤。

為確保保留輸出和錯誤的原始目標,您可以改為:

{
 {
   main "$@" 3>&- | tee -a -- "$LOG_FILE" >&3 3>&-
 } 2>&1 | tee -a -- "$LOG_FILE" >&2 3>&-
} 3> "$LOG_FILE" 3>&1

(未經測試)。

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