3

電子メール サーバー上でバックグラウンド プロセスとして実行される Perl スクリプトがあり、キュー ファイルとログ ファイルのさまざまなチェックを通じて侵害された電子メール アカウントを検出しようとします。USR1 シグナルのハンドラーを追加しました。これにより、スクリプトの実行中にスクリプト自体に関する情報が出力されます。これは、スクリプトをバックグラウンドで開始してから、次のように USR1 シグナルを送信するとうまく機能します。

./myscript.pl &
kill -USR1 (PID)

問題は、そのシェル セッションを終了してから再度接続するとkill -USR1、スクリプトの STDOUT に関連付けられた TTY がなくなったため、コマンドを使用しても出力が得られないことです。

したがって、Perl でシグナルを送信したユーザーまたはシェル プロセスの TTY を取得し、出力を STDOUT ではなく TTY に戻す方法があるかどうか疑問に思っています。シグナル ハンドラーで使用POSIX::ttyname(1)してみましたが、USR1 シグナルを送信したユーザーの TTY ではなく、スクリプトの STDOUT (この場合は空の値) の TTY が返されます。

シグナルを生成したプロセスの PID と UID を提供するPOSIX の Perldoc を見ましたがPOSIX::sigaction、Perl でその情報から TTY 名を取得する良い方法があるかどうかはわかりません。

どんな助けでも大歓迎です!ありがとう!

4

3 に答える 3

2

あなたが求めていることに関する2つの主な問題は、

  1. 呼び出し元のシェルが終了すると、TTY がなくなる/削除される私の Linux システムでは、STDOUT を開いてファイルにリダイレクトし、そのファイルのリンク
    を解除し た場合と同様の結果が得られます。ひどい、ひどいトリックをしない限り、その出力デバイスを取り戻すことはできません/proc

  2. 信号は送信者の TTY を伝送し
    ません最小限の仕様でも、仕様を拡張する実装でもありません

したがって、 tmuxGNU screenなどの端末マルチプレクサでユーティリティを実行するか、STDOUT を別の端末から確認できる他の出力にリダイレクトすることをお勧めします...ファイル、システムログ、データベースなどなど

于 2012-06-28T16:28:03.037 に答える
2

最も簡単な解決策は、質問へのコメントで nab が提案したものです。出力をファイル (おそらく $SIG{USR1} ハンドラー) に記録し、それを監視します。SIGUSR1 を取得するたびに上書きすることもできます。

私が実行している別の解決策は、ソケットハンドラーを作成することです。たくさんのモジュールを使用するつもりがない限り、これはもう少し複雑になります。私の解決策は、AnyEvent + Coroを使用することです。主な作業を 1 つの Coro スレッドに入れ、AnyEvent::Socket ::tcp_server(s) (ソケットおよび/または tcp ポート番号) を起動し、接続時に必要なことを行います (私の場合は、 $SIG{USR1} ハンドラで行うように詳細を出力し、接続を閉じます)。

実際のコード:

AnyEvent::Socket::tcp_server "unix/", "/tmp/cbstats.sock", sub {
    my $fh = shift;
    $fh->binmode(':utf8');
    $fh = unblock $fh;

    $self->handle_connection($fh, @_);

};

そして、私のものはインタラクティブなので、 を実行しsocat readline /tmp/cbstats.sockます。あなたの場合、socat stdout /tmp/your.socket出力が必要なときにいつでも実行できます。(ファイルシステムのアクセス許可を使用して、このデータを表示できるユーザーを制限/許可します。)

ここで少し気になる点があります。ソケットでリクエストを受信できるようにするには、sleep() の使用を停止する (または Coro バージョンを使用する) 必要があります。しかし、正直なところ、それはほとんど最小限でした。ただし、サーバーを AnyEvent タイマーを使用するように切り替えたので、スリープについて心配する必要さえありません。その後、複数のサーバーをそれぞれのタイマーでスムーズに動かしましたが、すべてうまくいきました。

幸運を。

于 2012-06-28T19:11:28.327 に答える
1

あなたのOSは何ですか?ps(1)任意のプロセスIDの制御ttyを出力できます。Linuxでは、/proc/<pid>/fd/1プロセス/proc/<pid>/fd/2の出力ストリームが接続されているターミナルまたはファイルへのシンボリックリンクです。

于 2012-06-28T16:15:17.910 に答える