如何防止子程序干擾bash提示?
有問題的應用程序是 DaVinci Resolve。我從終端啟動它。當我關閉它時,來自應用程序的消息“Socket Disconnected”被寫入終端輸出。然後 bash 提示符正常顯示。我開始輸入新命令,突然在終端“Socket Disconnected”中出現另一條消息。這會干擾我所做的輸入。它看起來像這樣:
[andrew@unihost ~]$ davinci-resolve ... # Now I exit the application. Host 'Fusion' Removed FusionScript Server [37457] Terminated Socket disconnected [andrew@unihost ~]$ ls ls Socket disconnected wtf!!!^C [andrew@unihost ~]$
影片展示:https ://youtu.be/arcCOjrN7kw
為什麼會發生這種情況,有沒有辦法防止這種情況發生?
我的猜測是主程序有一個子程序,即使在主程序死後它仍然活著。我找到了這個答案。是開發商的錯嗎?我可以以某種方式解決這個問題(對於子程序可能是 nohup)?
初步說明
我根本沒有測試
davinci-resolve
過。這個答案被設計為通用的。分析
davinci-resolve
您的 shell在將自身放回前台並列印提示之前等待退出。davinci-resolve
顯然,在主程序退出並且外殼做出反應後,主程序的某些子程序(或進一步的後代)會列印出不需要的消息。解決方案
解決方案可能很簡單:
davinci-resolve | cat
訣竅是
cat
在所有寫入管道的程序都關閉它們的管道末端之前不會退出。麻煩的孩子可能從 main 繼承了 stdoutdavinci-resolve
,所以cat
會等待它。通常,即使不需要的消息被列印到 stderr 或/dev/tty
(即它繞過我們的cat
),這也會起作用。重要的是孩子保持管道打開,即使它正在列印到其他地方。有以下缺點:
- 整個管道的退出狀態將來自於
cat
,而不是來自於davinci-resolve
。在某些 shell 中,您可以對它做一些事情。- 來自(及其後代)的 stdout 和 stderr
davinci-resolve
將失去同步,因為前者通過cat
而後者不通過。- 如果你
Ctrl
+c
那麼你將殺死cat
,可能在其他程序完成列印之前,所以你可能會錯過一些你確實想看到的輸出。此外,如果麻煩的消息被列印到 stderr,那麼無論如何它都會被列印出來,可能是在你看到提示之後。但是,您可以對+
cat
免疫:Ctrl``c
davinci-resolve | sh -c 'trap "" INT; exec cat'
- 麻煩的過程可能會提前關閉或重定向其標準輸出,但仍會列印到標準錯誤。在這種情況下
cat
不會等待它。- 麻煩的程序可能被設計為保留,不需要的消息並不意味著程序退出。如果這個過程仍然存在並保持管道打開,那麼我們的
cat
意志就會存在;你顯然不想要這個。似乎不太可能有任何davinci-resolve
遺骸的後代(除非有錯誤),但總的來說它可能會發生。由於其中一些原因,您可能希望通過 stdout和stderr傳遞
cat
. 免疫+仍然是一個好主意cat
:Ctrl``c
davinci-resolve 2>&1 | sh -c 'trap "" INT; exec cat'
現在請注意,您無法將 stderr
davinci-resolve
(及其後代)與 stdout 區分開來,它們都經過 viacat
及其 stdout。這應該不是問題,因為無論如何您都希望它們在終端中混合。如果您想單獨重定向或擷取它們,那麼您應該放棄我們的裝置並從頭開始。可能是麻煩的程序提前關閉或重定向其 stdout 和 stderr,並將不需要的消息直接列印到
/dev/tty
(範例)。在這種情況下,我們cat
無能為力。外殼函式
您可以將我們的解決方案實現為 shell 函式:
davinci-resolve() { command davinci-resolve "$@" 2>&1 | sh -c 'trap "" INT; exec cat' }
該函式支持將參數傳遞給
davinci-resolve
,但其退出狀態來自cat
,而不是來自davinci-resolve
程序(如果有問題,請參閱已經給出的連結以獲取想法)。