當編譯時間失敗時,編程語言Crystal當前不寫入STDERR。如果退出狀態不是0並且仍然返回退出狀態,我需要將STDOUT重定向到STDERR。退出狀態在Bash中不爲0時將STDOUT重定向到STDERR
回答
從字面上看,您的請求實際上是不可能的:重定向在命令啓動之前執行,而退出狀態僅在退出時才知道。
但是,您可以無條件地重定向到緩衝區,然後在知道退出狀態後將該緩衝區寫入stdout或stderr。
考慮類似於以下的包裝:
#!/bin/sh
if output=$("[email protected]"); then
printf '%s\n' "$output"
else
retval=$?
printf '%s\n' "$output" >&2
exit "$retval"
fi
...援引爲(如果這被保存爲stderr-wrapper
):
stderr-wrapper your-program arg1 arg2 ...
這太棒了!非常感謝!它對其他快樂道路沒有任何副作用。 –
這裏*有一個警告,因爲這段代碼會吃掉任何可能包含在程序輸出中的NULs(因爲NULs不能存儲在C字符串中,bash用於存儲內存)。如果這是一個問題,你可能會寫入一個文件。 –
如果預期的輸出太大,則臨時文件可能更安全 –
迴旋管的方法,這需要tac
和無害eval
,但既不是緩衝區變量也不是臨時文件。
演示腳本demo
,使用echo false ; false
模擬程序,它輸出到標準輸出和返回一個錯誤碼「」。
#!/bin/bash
out=([0]=/dev/stdout [1]=/dev/stderr)
{ { echo $1 ; $1 ; echo $? ; } | tac ; } | \
{ read x ; eval tac \> ${out[$x]} ; exit $x ; }
證明,使用annotate-output
:
annotate-output +'' ./demo true ; echo --- ; annotate-output +'' ./demo false
I: Started ./demo true
O: true
I: Finished with exitcode 0
---
I: Started ./demo false
E: false
I: Finished with exitcode 1
歸納該demo
成stderr-wrapper
:
對於
bash
:#!/bin/bash # Usage: stderr-wrapper program [ args... ] out=([0]=/dev/stdout [1]=/dev/stderr) { { [email protected] ; echo $? ; } | tac ; } | \ { read x ; eval tac \> ${out[$((x>0))]} ; exit $x ; }
對於POSIX殼,(這裏是
dash
):#!/bin/dash # Usage: stderr-wrapper program [ args... ] { { "[email protected]" ; echo $? ; } | tac ; } | \ { read x ; eval tac 1\>\&$(((x>0)+1)) ; exit $x ; }
的bash
版本是如何工作的:
- 運行有問題的程序,它輸出到標準輸出 。
- 之後立即打印錯誤代碼,也可以標準輸出。
- 反轉整個流與
tac
,所以錯誤代碼是第一個。 (昂貴,如果流很長。) read
一行,錯誤代碼,存儲在$x
。eval
$out
陣列成員對應於輸出應該去的設備,然後用tac
重新反向輸出到該設備。
- 1. Bash stderr和stdout重定向失敗
- 2. Tomcat將'stderr'內容重定向到'stdout'
- 3. 將子進程stderr重定向到stdout
- 4. 將stdout和stderr重定向到函數
- 5. Bash腳本 - 將子腳本stderr重定向到父級的stdout
- 6. 如何在Java中將子進程stdout/stderr重定向到主進程stdout/stderr?
- 7. 如何將stderr重定向到Ant中的stderr或stdout?
- 8. 重定向stdout和stderr的輸出?
- 9. 在DOSKEY宏中重定向STDERR和STDOUT
- 10. 重定向stdout/stderr在C中運行
- 11. 在bash腳本中測試stdout和stderr重定向
- 12. 實時重定向stdout和stderr
- 13. 爲每個線程重定向stdout/stderr
- 14. PERL無法將stdout和stderr重定向到輸出文件
- 15. 顯示bash shell stdout/stderr重定向行爲的備忘單
- 16. Stdout&stderr不自動啓動重定向
- 17. 在Python的子進程/ Popen中將stdout重定向到stderr
- 18. 如何將stderr/stdout重定向到我在C++中的日誌?
- 19. 在AIX中將STDERR&STDOUT重定向到/ dev/null失敗
- 20. Linux stdout stderr重定向到文件:與終端輸出不同
- 21. 爲什麼adb push/pull將STDOUT重定向到STDERR?
- 22. 如何將stdout和stderr重定向到文件AND仍只輸出stderr?
- 23. 如果將STDERR重定向到STDOUT並將STDOUT重定向到文件,爲什麼STDERR消息不會在文件中顯示?
- 24. 關閉stdout和stderr(1>& - 2>& - )修改退出狀態?
- 25. ksh將stdout和stderr重定向到不同的進程
- 26. 如何將raw_input重定向到stderr而不是stdout
- 27. 如何將stdout和stderr重定向到Python中的記錄器
- 28. 將stdout和stderr重定向到C++中的文件
- 29. 將stdout和stderr重定向到C++中的單個文件
- 30. 如何將stderr重定向到Ant JUnit目標中的stdout?
您嘗試過'some_bash_command.sh 2&1'嗎? – t0mm13b
重新定向在**程序啓動之前運行**。退出狀態僅在**該程序退出後才知道。你不能回到過去。 –