Bash

bash:使用變數來儲存 stderr|stdout 重定向

  • December 13, 2018

有沒有辦法通過變數重定向標準輸出和標準錯誤,比如在腳本中添加命令選項?

例如我有一個腳本:

#!/bin/bash -x
TEST=">/dev/null 2>&1"
OPT='-p -v'
mkdir $OPT 123/123/123 $TEST

我可以看到 OPT 被替換為-p沒有任何問題,並且 bash 將其解釋為選項。但重定向解釋為目錄名稱。

$ ./test.sh 
+ TEST='>/dev/null 2>&1'
+ OPT='-p -v'
+ mkdir -p -v 123/123/123 '>/dev/null' '2>&1'
mkdir: created directory `123/123'
mkdir: created directory `123/123/123'
mkdir: created directory `>/dev'
mkdir: created directory `>/dev/null'
mkdir: created directory `2>&1'

有什麼辦法可以說 bash, $VAR 是重定向,而不是目錄名稱。

PS。可能是我走錯了路,但我想從我的腳本中進行可選的詳細或非詳細輸出。但即使在非詳細模式下我也需要一些輸出,因此我不能只重定向整個 stdout 和 stderr,只能從我的腳本中的一些命令。

另一種解決方案可能如下:

#!/bin/bash

verbose=0

exec 3>&1
exec 4>&2

if ((verbose)); then
 echo "verbose=1"
else
 echo "verbose=0"
 exec 1>/dev/null
 exec 2>/dev/null
fi

echo "this should be seen if verbose"
echo "this should always be seen" 1>&3 2>&4

然後1>&3 2>&4僅添加到您希望查看其輸出的命令。

“如何”在其他答案中得到了很好的解釋;我想解決“為什麼”OP 的程式碼不起作用。

基調是在變數擴展之前標記了輸出重定向。 重定向實際上是在變數擴展之後執行的(因此您可以將輸出重定向到儲存在變數中的文件名),但 shell會在變數擴展之前辨識重定向以供以後處理。

換句話說,一旦變數被擴展,考慮重定向字元(<>等)就“為時已晚”,因為外殼程序已經確定了它將作為重定向處理的命令字元串的哪些部分。

如需進一步閱讀,請參閱下面列出的步驟 1 和 3:

LESS='+/^SIMPLE COMMAND EXPANSION' man bash

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