1つのプロセスが終了すると、残りのプロセスも終了できるように、「プロセスグループ」で複数のターミナルウィンドウを起動します。

1つのプロセスが終了すると、残りのプロセスも終了できるように、「プロセスグループ」で複数のターミナルウィンドウを起動します。

3つの端末エミュレータウィンドウを起動するスクリプトがあります。

#!/bin/sh

terminator --role='terminator-left' 2>/dev/null &
sleep 0.1
terminator --role='terminator-center' 2>/dev/null &
sleep 0.1
terminator --role='terminator-right' 2>/dev/null &

(私はopenbox設定ファイルで定義されている他のモニタにウィンドウを自動的に配置できるように--roleオプションを使用します)

私はこのスクリプトを別の仮想デスクトップで何度も起動しました。

ある種の「プロセスグループ」でこの3つの端末を起動し、そのうちの1つが終了したときに残りのすべてのプロセスを終了できるようにするにはどうすればよいですか。

重要:スクリプトの他のインスタンスから起動できるすべての端末を終了したくありません。パターンに一致するプロセスを終了するためにpkillまたはpgrepを使用することはできません。

つまり、仮想デスクトップ1と仮想デスクトップ2でスクリプトを実行しているとします。

これで、2つの異なる仮想デスクトップに3つのターミナルウィンドウがあります。

仮想デスクトップ1でターミナルをシャットダウンするときは、仮想デスクトップ2で実行されている他の3つの別々のウィンドウインスタンスに影響を与えず、残りの2つのウィンドウが自動的にシャットダウンされます。

私が説明することは可能ですか?

どうすればいいですか?

答え1

婦人声明:
私はopenboxで私の提案をテストする機会がありませんでした。 kde-plasmaでのみ確認しました。
私の解決策はwaitシェルの内部コマンドに依存しています。POSIX プログラママニュアルに記載されているように。特定の実装では、-nオプションを使用してスクリプトをより簡単にすることができます。


#!/bin/sh

ownkill()
{
        trap - CHLD
        pkill --signal 15 -P $$ 
}

terminator --role='terminator-left' 2>/dev/null &
sleep 0.1
terminator --role='terminator-center' 2>/dev/null &
sleep 0.1
terminator --role='terminator-right' 2>/dev/null &
trap ownkill CHLD
wait

このスクリプトは次のアイデアに基づいています。

  1. スタート3ターミネーター必要に応じて処理し、
  2. 完了するまでお待ちください。
  3. 残りのプロセスと同じ方法で、上記のプロセスの1つを終了するSIGCHLD信号を処理します。

注1(リセットハンドラ):aviroがコメントで正しく観察したように、シグナルハンドラはSIGCHLD処理をデフォルト値にリセットする必要があります。残りのプロセスを終了すると、他の(最大2つ)SIGCHLDがトリガーされるためです。
そうしないと、シェルはある種の再帰状況(ハンドラは自分で生成した信号を処理する必要がある)に陥り、シェルの実装に応じてある程度適切に管理されます。 (無害な警告から一部最大再帰深度を超えました。またはそれに相当するもの。間違い。 )

注2(待機するまでSIGCHLD基本処理を保持):Martin Vegterがコメントで正しく観察したように、このtrap ownkill CHLDコマンドはスタンバイコマンドの直前に配置する必要があります。
これをスクリプトの最初のコマンドで作成すると(以前のバージョンでとんでもなく提案したように)、最初のプロセスが終了するとすぐに専用sleepハンドラが起動します。

答え2

wait -nBashを使用すると、すべてのプロセスIDを簡単に収集し、プロセスが終了した場合(bashの場合)、すべてのIDが適切な信号で終了するのを待つことができます。

#!/bin/bash
terminator --role='terminator-left' 2>/dev/null &
pid1=$!
sleep 0.1
terminator --role='terminator-center' 2>/dev/null &
pid2=$!
sleep 0.1
terminator --role='terminator-right' 2>/dev/null &
pid3=$!
wait -n
kill -hup $pid1 $pid2 $pid3 2>/dev/null

PIDの1つが期限切れになったため、killエラーメッセージを回避するためにstderrをnullにリダイレクトします。

答え3

起動、制御、停止が簡単なので、systemd一時デバイスを使用することができます。シェルスクリプトが次のように見なされ、すぐに完了しないようにコマンドを最後に追加したら、./myscript次のように起動できます。wait -n

systemd-run --user --unit=mytest1 ./myscript

このコマンドはすぐにメッセージを返し、Running as unit: mytest1.service通常のコマンドを使用して作成した一時セルでどのプロセスが実行されているかを確認できます。

systemctl status --user mytest1

1つのコマンドですべてのプロセスを停止できます。

systemctl stop --user mytest1

--unit=同じスクリプトを複数回実行するには、毎回異なる名前を使用する必要があります。すべてで始まる場合は、すべてをtest確認するか、を参照して停止できますtest*

バラより男性システムの実行--setenv=、、、--working-directory=など、便利なさまざまなオプションについて学びます --collect--waitコマンドの最後でスクリプトに引数を渡すこともできますsystemd-run

関連情報