使 tmux 阻塞直到程式完成

使 tmux 阻塞直到程式完成

tmux 的遠端控制功能給我留下了深刻的印象:

tmux new-window -t p12346 'echo foo;sleep 10' 

這會在名為 p12346 的會話中建立一個新窗口,並且不會在螢幕上列印任何內容。太棒了。但是我要怎麼告訴上面的指令等到睡眠完成後再回來呢?即我希望執行相同的操作,但需要 10 秒來執行:

time tmux new-window -t p12346 'echo foo;sleep 10' 

背景

如果這是可行的,那麼它可能會成為 GNU Parallel 的功能:目前正在運行的作業可以透過其每個視窗進行訪問tmux,因此您可以即時追蹤每個作業的進度。

因此tmux不會在前台運行:用戶需要附加到它。

答案1

多路復用器1.8 引入了wait-for可以幫助做你想做的命令:

time tmux new-window -t p12346 'echo foo;sleep 10;tmux wait-for -S p12346-neww-done' \; \
          wait-for p12346-neww-done

「通道」名稱(p12346-neww-done在上面的範例中)可以是您喜歡的任何名稱(只要在兩個地方都相同;如果您預計可能會同時進行多個調用,那麼您可能還希望為每個調用使用唯一的值)。重要的是你在命令之後“等待”信號new-window(作為同一命令的一部分)多路復用器命令,因此轉義分號:多路復用器需要處理它,而不是 shell)並發送信號作為視窗命令的最後一步。

如果您需要更穩健地防止命令序列以醜陋或不方便的方式中止,那麼您可以嘗試使用 shell 陷阱來發送訊號(為了可讀性而重新排列了一點(?)):

time \
tmux new-window -t p12346 '
       trap "tmux wait-for -S p12346-neww-done" 0
       echo foo
       sleep 10
       ' \; wait-for p12346-neww-done

答案2

您可能會發現以下替代方法更合適:

外部 tmux:

mkfifo fifo && tmux new -d '(echo foo;sleep 3) 9> fifo' && time cat fifo

tmux 內部:

mkfifo fifo && tmux new-window '(echo foo;sleep 10) 9> fifo' && cat fifo 

與此的一個區別wait-for是,這種方法就像死人開關一樣:即使由於某種原因該wait-for -S命令永遠無法運行,它也會起作用。

另一個區別是,這將等待主進程的所有子進程退出(除非它們明確關閉其他檔案描述符,這對於嘗試將自己置於後台的程式來說很常見)。

說明:該cat指令將等待,直到有東西打開 FIFO 的另一端,然後退出全部該檔案描述符的實例被關閉,當持有該檔案描述符的所有進程退出時,就會發生這種情況。由於檔案描述符的屬性,該效果會傳播到子進程,預設情況下,子進程繼承父進程的開啟檔案描述符。

相關內容