Bash

如何在變數中重定向標準錯誤,但在控制台中保留標準輸出

  • October 9, 2018

我的目標是呼叫命令,在變數中獲取 stderr,但在螢幕上保留標準輸出(並且只有標準輸出)。是的,這與大多數人的做法相反:)

目前,我擁有的最好的是:

#!/bin/bash
pull=$(sudo ./pull "${TAG}" 2>&1)
pull_code=$?

if [[ ! "${pull_code}" -eq 0 ]]; then
 error "[${pull_code}] ${pull}"
 exit "${E_PULL_FAILED}"
fi

echo "${pull}"

但這只能在成功的情況下以及命令完成後顯示標準輸出。我想直播標準輸出,這可能嗎?

編輯

感謝@sebasth,並藉助將 STDERR 和 STDOUT 重定向到沒有臨時文件的不同變數,我寫了這個:

#!/bin/bash
{
 sudo ./pull "${TAG}" 2> /dev/fd/3
 pull_code=$?
 if [[ ! "${pull_code}" -eq 0 ]]; then
   echo "[${pull_code}] $(cat<&3)"
   exit "${E_PULL_FAILED}"
 fi
} 3<<EOF
EOF

我承認這不是真的“美麗”,看起來很棘手,而且我真的不明白為什麼需要heredoc …

這是實現這一目標的更好方法嗎?

只需使用:

{ err=$(cmd 2>&1 >&3 3>&-); } 3>&1

cmd在保持其標準輸出不變的情況下獲得標準錯誤(這里通過使用 fd 3原始標準輸出(用 複製3>&1)帶入命令替換(>&3在我們將 fd 2 重定向到由命令替換創建的管道之後恢復2>&1)) .

您可以使用Stéphane Chazelas提供的答案並稍作修改:僅重定向 stderr 並且不要使用命令替換來執行您的命令。

{
 command 2> /dev/fd/3
 res=$?
 err=$(cat<&3)
} 3<<EOF
EOF

printf 'stderr: %s\n' "$err"

的輸出command通常在 stdout 中,而 stderr 在err變數中。

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