2009-12-04 8 views
8

UNIX-yの方法では、プロセスを開始し、バックグラウンドにして、そのプロセスの寿命をシェルに結びつけようとしています。プロセスを始動したシェルにプロセスの寿命を結ぶ

私が話しているのは、単にプロセスをバックグラウンドにするだけではなく、プロセスがSIGTERMに送られるようにするか、閉じたオープンファイルディスクリプタを持っているか、何かシェルが終了するときです。シェルのユーザーが明示的にプロセスを強制終了したり、「あなたはジョブを実行しています」という警告を出す必要はありません。

最終的には、各シェルに対して一意に実行し、そのシェルと共に状態を運び、シェルが終了すると閉じることができるプログラムが必要です。

IBMのDB2コンソールコマンドは、このように動作します。データベースに接続すると、データベース状態と接続を持ち、それをシェルに結びつける "db2bp"プロセスが生成されます。複数の異なる端末またはssh接続でそれぞれ独自のdb2bpプロセスを使用して接続できます。これらの接続がクローズされると、適切なdb2bpプロセスが終了し、その接続がクローズされます。

DB2クエリーは、db2コマンドで開始されます。これは、適切なdb2bpプロセスに渡すだけです。私はそれがどのように db2bpプロセスと通信するのか分かりませんが、stdinに固有のキーとして接続されているttyデバイスを使用していますか?私もそれを理解する必要があると思います。

私はtty操作を行うことは一度も書かなかったので、どこから始めるべきかわからない。私はシェル出口で自動的に殺されるプロセスを生成することができれば、残りを把握できると思います。誰でもDB2がどのようにそれを行うのか知っていますか

答えて

2

シェルがサブシェルでない場合は、次の操作を実行できます。実行中のプロセスがあることを訴えてからシェルを防ぐことができますプロセスをDisowning

$ ttywatch commandline... & disown 

、いつターミナル:

#!/usr/bin/perl 
my $p=open(PI, "-|") || exec @ARGV; sleep 5 while(-t); kill 15,$p; 

は次にとしてあなたのプログラムを実行します。「ttywatch」と呼ばれるスクリプトに次のように入れて終了すると、5秒以内にSIGTERM(15)がサブプロセス(あなたのアプリケーション)に配信されます。

シェルがサブシェルでない場合は、少なくともttywrapのようなプログラムを使用して、少なくとも独自のttyを与えてから、上記のトリックが機能します。

+0

うん、それは動作します!私はdb2がどのようにそれを行うのかを理解しましたが、これはまったく同じではありませんが、これは非常に短く単純です。私のperlはそれほど素晴らしいものではありません...(t)テスト中は何ですか? – Kyren

+0

ああ、見つかりました。 -tはデフォルトでstdinになり、ファイルがttyに開かれているかどうかをテストします。かなり滑らかです。 – Kyren

0

シャットダウン時に実行中の子プロセスにシェルがSIGHUPシグナルを送信している必要があります。シェルを終了するときに、シャットダウンするためにアプリケーションにSIGHUPハンドラを追加しようとしましたか?

+0

私はちょうどそれを試みたが、私はそれが動作するとは思わない。 あなたの背景の場合、このpythonのプロセス: 輸入OS、SYS、時間、信号 DEFハンドラ(シグナム、フレーム): '後の信号をキャッチ出' 印刷、シグナムのsys.exit(0) 信号。 time.sleep(1) その後、シェルは終了時にジョブを実行している(または設定されている場合は、プロセスを永久に実行している)ことについて依然として不平を言います。私がSIGHUPを殺すまで、プロセスはSIGHUPに送られないようです。 – Kyren

+0

うわー、私は実際にスタックオーバーフローのフォーマットに失敗します。 – Kyren

0

あなたの実際の問題は、あなたのプロセスではなくシェルである可能性がありますか?私の理解はJim Lewisと同じです。シェルが死んだら、子供たちはSIGHUPを受けるべきです。しかし、あなたが不満を抱いているのは、アクティブな子を持つ実行中のシェルを誤って削除しないようにするシェル(またはおそらく端末)です。

この動作が設定可能かどうかを確認するには、シェルまたは端末のマニュアルをお読みください。私のMacBook上のbashのマニュアルから

:SIGHUPを受信すると、デフォルトで

シェルが終了。終了する前に、対話型シェルは、実行中または停止したすべてのジョブにSIGHUP を再送信します。停止したジョブには、SIGHUPを受け取るためにSIGCONTが送信されます。 シェルがシグナルを特定のジョブに送信しないようにするには、disown -hを使用してSIGHUPを受け取らないようにマークするか、またはのジョブテーブルから削除する必要があります(SHELL BUILTIN COMMANDSを参照)。

shoptでhuponexitシェルオプションを設定した場合、対話型 ログインシェルが終了すると、bashはすべてのジョブにSIGHUPを送信します。

正しい方向に指摘する可能性があります。

+0

それはありますが、私はそれをする必要はありません。以前は見ていなかったが、bashとzshのマンページでそのオプションを見つけた。私はそれをする必要はありません。ええ、bashやzshを設定して、すべてのバックグラウンド・プロセスを一旦終了させると、マンページはそうしないと言っても、DB2はそれを必要としないように見えます。 DB2はどうしていますか? – Kyren

+0

'私はそれほど助けにならない。私はこれが望ましい機能であることに同意し、それを行う方法を知らないだけです。 – dmckee

+0

まあ、自分自身を修正するために、彼らは殺されていません - あなたが言ったように、彼らはSIGHUPされています:)また、常にNO_CHECK_JOBSとNO_HUPを一緒に使用することを提案するzshのマンページです。しかし、まだ、私は自分のシェルを再構成する必要はありません – Kyren

2

さて、私はそれを理解したと思う。私はそれも複雑すぎていた:)

私はすべてのdb2はデーモンizing db2bpだと思うし、db2bpは親PID(シェルのPID)でwaitpidを呼び出し、waitpidが戻った後に終了します。

db2コマンドとdb2bpの間の通信は、親シェルPIDに基づくファイル名のfifoを介して行われているようです。

メーリングリストの単純な私は好奇心旺盛で、誰のため:)

を考えていたよりは、この全体の努力は、シェルにPythonやGroovyのインタラクティブセッションを結ぶことができるようにし、そう簡単にジャンプしながら私は、コードをテストすることができデータベース接続と一時的なクラス/変数を保持するセッションから解放されます。

ありがとうございました!

関連する問題