プログラムが完了するまで 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

tmux1.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(同じtmuxコマンドなので、セミコロンをエスケープします。tmuxシェルではなく、ウィンドウがそれを処理して、ウィンドウのコマンドの最後のステップとしてシグナルを送信する必要があります。

コマンド シーケンスが不格好または不便な方法で中止されることに対してもう少し堅牢にする必要がある場合は、シェル トラップを使用してシグナルを送信してみてください (読みやすくするために少し並べ替えました)。

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 

との 1 つの違いはwait-for、このアプローチはデッドマン スイッチとして動作する点です。つまり、何らかの理由でコマンドがwait-for -S実行されない場合でも機能します。

もう 1 つの違いは、メイン プロセスのすべての子プロセスが終了するまで待機することです (子プロセスが他のファイル記述子を明示的に閉じない限り、これはバックグラウンドで動作しようとするプログラムでは一般的です)。

説明:catコマンドはFIFOのもう一方の端が開くまで待機し、その後終了します。全てそのファイル記述子のインスタンスは閉じられます。これは、それを保持しているすべてのプロセスが終了したときに発生します。デフォルトでは、子プロセスは親の開いているファイル記述子を継承するというファイル記述子の特性により、効果は子プロセスに伝播します。

関連情報