如何正確啟動程序並在稍後階段重定向其執行輸出(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 程序)進行通信?
筆記:
這是“如何重定向正在執行的程序的輸出?”系列的一個問題,但它不是從“操作我啟動程序但我忘記重定向輸出。現在我想做它”這一點開始,但相反:“我如何啟動一個程序,其明確目的是在稍後階段將輸出重定向到其他地方?”。
當無法(或不方便)修改程序的原始碼時,我打算使用這樣的程序。
我讀到有可能
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 pid
或kill %1
這樣做)。當第二次我將要求FIFO在終端上轉儲(再次使用
cat MyOutput
)時,它將從那一刻開始轉儲輸出。注意事項和警告:
- 直到我不會要求轉儲
FIFOs
它會保存所有輸出。正如我第一次問的那樣,它會全部沖洗掉。
- 我可以重定向(或附加)到另一個文件
cat MyOutput >> NewRealFile
- 我也可以
cat MyOutput
從另一個終端使用!- 警告:如果我要求 2 個不同的程序(或實例)將輸出重定向到相同
FIFOs
的通量將被合併(沒有先驗方法來區分該行來自哪個程序)。- 警告:如果我詢問 2 次或更多次(可能來自不同的終端),它將為每個請求提供一行,將輸出拆分給請求者。也許有一個安全的解決方法……