如何正確啟動程式並能夠在稍後階段重定向其運行輸出(stdout 和 stderr)?

如何正確啟動程式並能夠在稍後階段重定向其運行輸出(stdout 和 stderr)?

問題很簡單:我發現有可能很有用開啟(和關閉)我需要的每個時刻某個正在運行的程式的輸出。更準確地說,我希望能夠自由地將它們的標準輸出(和錯誤)從當前 shell 重定向到另一個 shell、重定向/dev/null到檔案或返回到原始 shell。

我尋找一些直接(且安全)的東西,利用我所知道的事實提早我將打開和關閉輸出。我也發表一個答案。


下面是我的第一次嘗試。假設我在 35 號外殼工作。

$ who am I                     # the command line to ask where am I
myuser  pts/35  ...            # The answer 

我的嘗試從指向該終端的符號連結開始

ln -s /dev/pts/35  MyOutput  # The command to link

這個想法是啟動程序並將重定向設置為該鏈接

./Execute_program > MyOutput

它有效,它將輸出重定向到我的終端,但是當我發出更改連結的命令時,

ln -sf  /dev/null  MyOutput

連結發生變化,但重定向不會改變我多麼希望。它不會因正在運行的進程而改變。如果我以相同的方式啟動一個新程序,重定向將遵循連結的新規定。
如果我再次開始並將輸出連結/dev/null設為預期抑制,但當我再次更改連結時,重定向不會更改。
如果我做一個鏈接到一個鏈接,我會得到相同的結果。使用hard link不會改變情況。

可悲的是shell 在啟動時擴展命令列。

是否有可能以類似的方式完成這項工作,或者我可以找到如何與連結已更改的進程(或 PPID 進程)進行通訊?


筆記:

這是「如何重定向正在運行的進程的輸出?」系列的一個問題,但它並不是從這一點開始的“Ops 我啟動了程序,但忘記重定向輸出。現在我想這樣做”,但從相反的角度來看:「我如何啟動一個程序,其明確的目標是在稍後階段將損失重定向到其他地方?」。

當不可能(或不方便)修改程式的原始程式碼時,我打算使用這樣的過程。
可以disown處理、使用screen並從一個螢幕傳輸到另一個螢幕...或使用調試器來攔截進程...所有這些解決方案都可以透過大量的經驗和努力來發揮作用,但其中一些解決方案也呈現一定比例的風險。

答案1

我透過mkfifo建立一個命名管道找到了一個解決方案,或者先進先出
就像建立符號連結一樣簡單,並且可以使用 shell 允許的所有重定向。

mkfifo MyOutput

ls -l給出

0 prw-r--r-- 1 My_username My_username  0 May 11 17:45 MyOut|

我可以透過重定向到該連結來啟動該程序

./Execute_program > MyOutput  &  cat MyOutput 

並且輸出開始在終端上流動。

如果我按ctrl+c我會中斷流程,但不會中斷正在運行的進程(我必須使用類似kill pid或 的東西kill %1來執行此操作)。
當第二次我會問先進先出要在終端機上轉儲(再次使用cat MyOutput),它將開始轉儲該時刻的輸出。

注意和警告:

  • 直到我不會要求FIFOs它的轉儲將保存所有輸出。
    正如我第一次問的那樣,它會沖走全部。
  • 我可以重定向(或附加)到另一個文件cat MyOutput >> NewRealFile
  • cat MyOutput我也可以從另一個終端使用!
  • 警告:如果我要求 2 個不同的程式(或實例)將輸出重新導向到相同的FIFOs通量將被合併(沒有先驗區分該行來自哪個程式的方法)。
  • 警告:如果我詢問兩次或多次(可能來自不同的終端),它將為每個請求提供一行,將輸出拆分給請求者。也許有一個安全的解決方法...

答案2

如果我正確理解你的問題:

script 1>>~/out.fifo 2>>~/error.fifo 

然後要監視你可以執行以下操作:

watch cat ~/out.fifo

您可以使用真實文件而不是 Fifos

script 1>/tmp/$0-out 2>/tmp/$0-error

然後 tail -f 它們,當您再次運行腳本時它們將被替換。

我更喜歡第二種方法,或只使用多工器(即螢幕或本周流行的轉世)

screen -t "name" bash -c 'script'

然後

screen -r

「監視」並按 ctrl+ad 分離。

如果您想在運行後查看輸出,請確保在腳本末尾暫停。

答案3

如果我是你,我只是將輸出重定向到一個文件,然後當我想查看輸出時尾部該文件...如果你認為輸出會相當長,你可能想限制該文件的大小,或者如果您認為輸出會相當快,則將檔案寫入記憶體而不是磁碟上,但如何做這些事情是另一個問題。

相關內容