Linux

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

  • July 3, 2017

問題很簡單:我發現能夠在我需要的每一刻*打開(和關閉)某些正在執行的程序的輸出是很有用的。*更準確地說,我希望能夠自由地將他們的標準輸出(和錯誤)從目前 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 程序)進行通信?


筆記:

這是“如何重定向正在執行的程序的輸出?”系列的一個問題,但它不是從“操作我啟動程序但我忘記重定向輸出。現在我想做它”這一點開始,但相反:“我如何啟動一個程序,其明確目的是在稍後階段將輸出重定向到其他地方?”。

當無法(或不方便)修改程序的原始碼時,我打算使用這樣的程序。

讀到有可能disown處理、使用screen和從一個螢幕轉移到另一個螢幕……或者使用調試器來攔截這個過程……所有這些解決方案都可以通過大量的經驗和努力來發揮作用,但有些其中也存在一定比例的風險。

我通過 找到了一個解決方案mkfifo,它創建了一個命名管道或FIFOs

就像創建符號連結一樣簡單,並且可以使用 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 pidkill %1這樣做)。

當第二次我將要求FIFO在終端上轉儲(再次使用cat MyOutput)時,它將從那一刻開始轉儲輸出。

注意事項和警告:

  • 直到我不會要求轉儲FIFOs它會保存所有輸出。

正如我第一次問的那樣,它會全部沖洗掉

  • 我可以重定向(或附加)到另一個文件cat MyOutput >> NewRealFile
  • 我也可以cat MyOutput從另一個終端使用!
  • 警告:如果我要求 2 個不同的程序(或實例)將輸出重定向到相同FIFOs的通量將被合併(沒有先驗方法來區分該行來自哪個程序)。
  • 警告:如果我詢問 2 次或更多次(可能來自不同的終端),它將為每個請求提供一行,將輸出拆分給請求者。也許有一個安全的解決方法……

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