bash:將stdout捕獲到變量但仍在控制台中顯示




ubuntu tee (3)

Op De Cirkel的回答是正確的。 它可以更簡化(避免使用cat ):

exec 5>&1
FF=$(echo aaa|tee /dev/fd/5)
echo $FF

我有一個bash腳本調用幾個長時間運行的進程。 我想根據處理原因將這些調用的輸出捕獲到變量中。 但是,因為這些是長時間運行的進程,所以我希望rsync調用的輸出實時顯示在控制台中,而不是事後。

為此,我found了一種方法,但它依賴於將文本輸出到/ dev / stderr。 我覺得輸出到/ dev / stderr並不是一種好的做事方式。

VAR1=$(for i in {1..5}; do sleep 1; echo $i; done | tee /dev/stderr)

VAR2=$(rsync -r -t --out-format='%n%L' --delete -s /path/source1/ /path/target1 | tee /dev/stderr)

VAR3=$(rsync -r -t --out-format='%n%L' --delete -s /path/source2/ /path/target2 | tee /dev/stderr)

在上面的例子中,我調用rsync幾次,我想看到文件名在處理時,但最後我仍然想要輸出變量,因為我稍後會解析它。

是否有一種“更清潔”的方式來實現這一目標?

如果它有所作為,我使用的是Ubuntu 12.04,bash 4.2.24。


在shell中復制&1(在我的考試中為5)並在子shell中使用&5(這樣你將寫入父shell的stdout(&1)):

exec 5>&1
FF=$(echo aaa|tee >(cat - >&5))
echo $FF

將打印aaa兩次,因為子shell中的迴聲,並且第二次打印變量的值。

在你的代碼中:

exec 5>&1
VAR1=$(for i in {1..5}; do sleep 1; echo $i; done | tee >(cat - >&5))
# use the value of VAR1

這是捕獲stderr和命令退出代碼的示例。 這是基於羅素戴維斯的答案。

exec 5>&1
FF=$(ls /taco/ 2>&1 |tee /dev/fd/5; exit ${PIPESTATUS[0]})
exit_code=$?
echo "$FF"
echo "Exit Code: $exit_code"

如果文件夾/taco/存在,則將捕獲其內容。 如果該文件夾不存在,它將捕獲錯誤消息,退出代碼將為2。

如果省略2>&1則僅捕獲stdout







process-substitution