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
このスクリプトは次のアイデアに基づいています。
- スタート3ターミネーター必要に応じて処理し、
- 完了するまでお待ちください。
- 残りのプロセスと同じ方法で、上記のプロセスの1つを終了するSIGCHLD信号を処理します。
注1(リセットハンドラ):aviroがコメントで正しく観察したように、シグナルハンドラはSIGCHLD処理をデフォルト値にリセットする必要があります。残りのプロセスを終了すると、他の(最大2つ)SIGCHLDがトリガーされるためです。
そうしないと、シェルはある種の再帰状況(ハンドラは自分で生成した信号を処理する必要がある)に陥り、シェルの実装に応じてある程度適切に管理されます。 (無害な警告から一部最大再帰深度を超えました。またはそれに相当するもの。間違い。 )
注2(待機するまでSIGCHLD基本処理を保持):Martin Vegterがコメントで正しく観察したように、このtrap ownkill CHLD
コマンドはスタンバイコマンドの直前に配置する必要があります。
これをスクリプトの最初のコマンドで作成すると(以前のバージョンでとんでもなく提案したように)、最初のプロセスが終了するとすぐに専用sleep
ハンドラが起動します。