Bash
如何在變數中重定向標準錯誤,但在控制台中保留標準輸出
我的目標是呼叫命令,在變數中獲取 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
變數中。