1

誰かがすでに質問していると思っていたので、この質問を投稿するのをためらっていましたが、多くの精査の後、空になったので、ここにあります.

背景: 少数のスクリプト/コマンドをリモートで実行できるようにするローカル エージェント (C で記述され、TCP 経由でリッスン) を実行しています。(具体的には、Web インターフェース経由。) スクリプト自体は、バイナリ、bash、または perl スクリプトの混合物であり、リストで許可されている限り、エージェント自体はあまり気にしません。

(これは企業の内部ネットワーク上にあり、これは非常に初期の段階にあるため、現時点ではセキュリティのメリットについて議論しないでください。)

プロセスを起動する C エージェント コードは次のとおりです。

sprintf(mrun, "%s %s 2>&1", file, args);
mexec = popen(mrun, "r");
[read some returned buffer]
pclose(mexec);

このアプローチは、スクリプトがコマンドを実行する (またはフォアグラウンドで実行する) だけであれば、外部の bash スクリプトと perl スクリプトの両方でうまく機能します。ただし、最近、スクリプトを拡張してデーモン (この場合は名前付き) の再起動を含める必要がありました。

スクリプト自体 (bash) は単純です。

#!/bin/bash
pkill -9 named
/local/mnt/named/sbin/named -c /local/mnt/named/var/named.conf &
echo "restarted"

私が直面している問題は、C エージェント経由で実行するとスクリプトが終了しない (つまり、再起動してもエコーされない) ため、制御が返されず、TCP ソケットが解放されないことです。エージェントに関する限り、プロセスはまだ実行中です。ターミナルからスクリプトを実行すると、正常に動作し、制御が返されます。

Cデーモンからフォークされたときとbashターミナルから呼び出されたときにスクリプトを正常に実行できるようにする何かが欠けていますか?

私は nohup を知っており、他のすべてが失敗した場合はそれを使用できると思いますが、これを行うための他の種類の回避策があるかどうか興味がありました。

4

1 に答える 1

0

上記のコメントからのフィードバックに基づいて、いくつかの追加のリダイレクトのおかげで、デーモン プロセスの起動後もスクリプトが動作し続けることができました。

/local/mnt/named/sbin/named -c /local/mnt/named/var/named.conf </dev/null &> /dev/null &

そのため、fork0 にその知識を提供していただき、ありがとうございます。

その後、スクリプトが機能したにもかかわらず、TCP ソケット接続が適切に閉じられないことに気付きました。以下にさらに情報を追加し、多くの調査を行った結果、子プロセスは親プロセス (ソケットを含む) からファイル記述子を継承 (および開いたまま) することが判明しました。

子プロセスを否認する方法を探しましたが、実際に機能するものは見つかりませんでした (または、エージェント全体を書き直す必要はありませんでした)。

最後に、この質問に出くわしました。これは関連していますが、私が使用しているプログラミング言語ではありません。

親の fds を継承せずに os.execute

これには基本的に、子プロセスがコード内で開いているファイル記述子を閉じて、親によって閉じられるように解放することが含まれていました。(おもう?)

named を開始する前に、これを行うために bash スクリプトに数行追加しましたが、機能します。

for i in `nawk 'BEGIN{ for(i=1;i<=255;i++) print i}'`
do
eval exec `echo $i | sed -e 's/.*/&<\&-/'`
done

(Solaris と Linux で実行する必要があるため、seq の代わりに nawk を使用します。)

いくつかの基本的なテストでは、これによりソケットを閉じることができないという主要な問題が解決されたことが示されていますが、これが私が認識していない他の影響をもたらすかどうかについて、さらに調査を行う必要があります. これを達成するためのより良い、より安全な方法もあるかもしれませんが、少なくとも私は正しい方向に進んでいます.

于 2012-07-27T22:52:21.663 に答える