web-dev-qa-db-ja.com

UNIXシステムの別のプロセスからファイル記述子を閉じる方法

コマンドlsofを使用して、実行中のすべてのプロセスのファイル記述子を取得できますが、私がやりたいのは、そのプロセス内にいなくても、それらの記述子の一部を閉じることです。これはWindowsで実行できるため、一部のアプリケーションのブロックを簡単に解除できます。

そのためのコマンドや機能はありますか?

26
Seb

Windowsでは、実行中のカーネルにデバイスドライバーを挿入して実行するプログラムを誰かが作成したため、プログラムを使用して実行できます。ちなみに、これを行うのは危険な場合があります。壊れたアプリケーションが使用していたハンドルを閉じた後、アプリケーションはハンドルが閉じられたことを認識せず、アプリケーションが他の無関係なオブジェクトを開いたときに認識しないためです。同じハンドルが他の無関係なオブジェクトを参照する可能性があること。あなたは本当にできるだけ早く壊れたアプリケーションを殺したいです。

Linuxでは確かに同じ種類のテクニックを使うことができます。実行中のカーネルにモジュールを挿入するプログラムを作成します。モジュールと通信し、どのハンドルを閉じるかを伝えます。そうすることも同様に危険です。

2

なぜこれを行おうとしているのかわかりませんが、gdbを使用してプロセスに接続し、fdでclose()を呼び出すことができるはずです。例:

1つのシェルで:猫

別のシェルで:

$pidof cat
7213

$gdb -p 7213

...
lots of output
...

(gdb)

ここで、gdbにclose(0)を実行するように指示します。

(gdb) p close(0)

$1 = 0

(gdb) c

Continuing.

Program exited with code 01.
(gdb)

最初のシェルでは、次の出力が得られます。

cat: -: Bad file descriptor

cat: closing standard input: Bad file descriptor
76
Andreas

そうは思いませんが、lsofはファイルを開いたプロセスのPIDを提供するので、プロセスを完全に強制終了するか、少なくともプロセスを終了させるためのシグナルを送信することができます。

3

疑わしい。ファイル記述子はプロセスローカルであり、stdoutはすべてのプロセスに対して1ですが、もちろん一意のストリームを参照します。

おそらく、解決しようとしているブロッキングの問題について、より詳細な情報が役立つでしょう。

2
unwind

UnixではWindowsよりもこれを行う必要がはるかに少ないです。

Windowsでは、ほとんどのプログラムは開いているファイルを「ロック」(実際には共有を拒否)する傾向があるため、別のプログラムで読み取り/書き込み/削除することはできません。

Unixでは、ほとんどの場合、これは発生しません。 Unixでのファイルロックはほとんどが助言であり、通常の読み取り/書き込み/削除操作ではなく、他のロックの試みのみをブロックします。プロセスの現在のディレクトリを削除することもできます。

これがUnixの通常の使用法で発生する唯一の状況は、ファイルシステムをアンマウントしようとするときです(マウントされたファイルシステムへの参照は、アンマウントをブロックする可能性があります)。

2
CesarB