2

リモート データベースからプルされた、zip のようなファイル コンテナーにラップされた何千ものバイナリを処理しています。readelf などのツールを使用してこれらのバイナリの内容を分析する必要がありますが、バイナリをディスクに書き込むために不要な IO が発生するのを避けたいと考えています。

subprocess.Popen を呼び出して、コマンドがファイルとして理解するコマンドライン ユーティリティにメモリ内ファイルを渡す方法はありますか? ファイル記述子を標準入力に割り当てようとしましたが、ユーティリティが期待どおりに標準入力からファイルの内容を読み取れません。

with zipfile.ZipFile(file,'r') as z:
  with z.open(binary_path) as bin:
    subprocess.Popen(['readelf','-d'],stdin=bin)

また、必要な引数をファイル記述子への参照に直接設定しようとしましたが、それも無駄であることが証明されています。

with zipfile.ZipFile(file,'r') as z:
  with z.open(binary_path) as bin:
    subprocess.Popen(['readelf','-d',bin])

私が試みていることは可能ですか、それともディスクに書き込んでそこから分析することに頼るべきですか?

どうもありがとう!

4

1 に答える 1

1

ゼロス、なぜ、または類似のものpopen readelfを使用する代わりに、する必要があるのですか? PyPI で「elf」をlibelfすばやく検索すると、多くの可能性が示されます。それらを調べましたか?

まず、多くのプラットフォームでは、すべての I/O がキャッシュを通過することになるため、削除するためだけに最終的にすべてをディスクにフラッシュすることになっても、実際には速度が低下することはありません (決して行う)。を慎重に使用するとmmap、ディスクへのフラッシュを回避できることがよくありますが、その必要さえない場合もあります。

本当に、最初にテストして、過剰な I/O が本当に速度を低下させているかどうかを確認します。そうでない場合は、心配するのをやめてください。

ディスク I/O がないことを確認したい場合 (すべてのスワップを無効にしていると仮定しています。そうしないと、そもそもその考えが意味をなさないからです)、最も簡単な解決策は、実際にはそうではない一時ファイルを作成することです。ディスクにバックアップされます。

これを行う最も簡単な方法は、RAM ディスクを作成し、一時ファイルをそこに置くことです。

あるいは、ほとんどのプラットフォームには、ディスクにバックアップされないか、絶対に必要な場合にのみディスクにバックアップされる一時ファイルを作成する方法があります。残念ながら、stdlib の Python 関数でこれを行うことはできないと思います。その場合は、プラットフォーム固有のコードを作成する必要があります。

任意のバッファを stdin としてツールに渡したい場合は、簡単です。ただし、stdin を読み取るようにツールに指示する方法を知っておく必要があります。これは、多くの場合-c、オプションまたは-偽のファイル名として渡したり、ファイル名をまったく渡さなかったりすることを意味します。マンページを読んでどちらを確認してください。例えば:

with zipfile.ZipFile(file,'r') as z:
    with z.open(binary_path) as bin:
        subprocess.Popen(['gzip','-dc'], stdin=bin)

残念ながら、一部のツールはこの方法では機能しません。多くの場合、単なるストリームではなくシーク可能なファイルが必要なためです。私readelfはそれらの1つであると信じています。したがって、このオプションは使用できません。

また、任意の fd をツールに渡すには、ファイル名の代わりに任意の fd を取得する方法がツールに必要ですが、ほとんどの場合はそうではありません。

于 2012-12-12T19:58:01.790 に答える