9

python、perl、ruby、またはphpを書くとき、私はよく使用します...

PERL:
`[SHELL COMMAND HERE]`
system("[SHELL]", "[COMMAND]", "[HERE]")

Python
import os
os.system("[SHELL COMMAND HERE]")
from subprocess import call
call("[SHELL]", "[COMMAND]", "[HERE]")

ruby 
`[SHELL COMMAND HERE]`
system("[SHELL COMMAND HERE]")

PHP
shell_exec ( "SHELL COMMAND HERE" )

シェルでサブプロセスを生成すると、プログラムのパフォーマンスがどの程度低下しますか?たとえば、私はperlとlibcurlを使用してスクリプトを作成していましたが、libcurlのすべてのパラメーターを使用して、スクリプトを機能させるのは困難でした。libcurlの使用をやめて使い始めたところcurl、パフォーマンスが向上し、スクリプトがはるかに簡単になり、さらに、基本的なperl(cpanモジュールなし)と基本的なシェルユーティリティのみがインストールされているシステムでスクリプトを実行できました。

このサブシェルを生成することが悪いプログラミング手法と見なされるのはなぜですか?常に理論的には、言語内で特定のバインディング/同等のライブラリを使用するよりもはるかに遅いはずですか?

4

3 に答える 3

7

シェルコマンドの実行が悪い最初の理由は、保守性です。タスク間のコンテキスト切り替えは、言語切り替えなしでは十分に悪いものです。セキュリティも考慮事項ですが、コーディングの慣行により、セキュリティの重要性は低くなります(インジェクションを回避するなど)。

パフォーマンスに影響を与えるいくつかの要因があります。

  1. プロセスのフォーク:これにはしばらく時間がかかりますが、実行中のコードのパフォーマンスが良好な場合、これはそれほど重要ではなくなります。
  2. 最適化が不可能になる:コントロールが別のプロセスに渡されると、インタープリターまたはコンパイラーは最適化を実行できなくなります。また、最適化を実行することはできません。
  3. ブロッキング:シェルコマンドはブロッキング操作です。コードのネイティブ部分のようにスケジュールされることはありません。
  4. 解析:出力について何かを行う必要がある場合は、解析する必要があります。ネイティブコードでは、データはすでに関連するデータ構造になっています。解析もエラーが発生しやすくなります。
  5. コマンドラインの生成:実行可能ファイルのコマンドラインを生成するには、反復が必要になる場合があります。同じことをネイティブに実行するよりも多くのサイクルがかかる場合があります。

これらの問題のほとんどは、外部コマンドがループで実行されるときに発生します。これらのどれも問題にならない例を見つけるのは簡単かもしれません。

于 2013-03-07T22:31:11.853 に答える
4

フェリックスは、パフォーマンス関連の問題のいくつかを非常にうまく述べました。

セキュリティと保守性に関して、私は以下を提出します:

  1. 移植性/外部依存関係からの分離

    • もちろん、wgetLinuxを使用している場合は、シェルアウトして呼び出すことができます。WindowsまたはMacの場合、それはひどく死にます。組み込みのメソッドを使用するために書き直さなければならない理由を上司に説明するか、使用する必要のあるユーザー/同僚をサポートする必要があります。あなたのツール(どちらもとても楽しいものではありません)。

    • いつの日か、スクリプトが機能しなくなった理由を理解するために何時間も費やしますが、アップグレードされたバージョンの外部プログラムには異なるコマンドラインパラメーターが必要であり、コードが期待どおりに機能しなくなっていることがわかります。

  2. 1つの言語(Perl / Python / PHP)のエスケープ文字は、必ずしもシェル言語のエスケープ文字にマップされるとは限りません(例:SQLインジェクション攻撃は、おそらく1つの言語(HTML)のエスケープ文字が混合された結果です。別の言語(SQL))。

  3. ある言語ではデバッグは十分に困難です。別の言語のコマンドを生成するコマンドをデバッグしようとすると、さらに困難になります(特に、引用符をエスケープすると、\\\\\"some value\\\\\"...のような文字列になってしまう可能性があります)。

于 2013-03-08T00:32:00.770 に答える
3

シェルプロセスを生成することは悪い習慣だと誰が言いますか?独裁者に注意してください。いつそれを行うか、または行わないかを定義する厳格なルールはありません。あなたの例では、カールするために砲撃を開始したとき、プロジェクトをより速く終了し、パフォーマンスが向上しました。証拠は常にプリンにあります。

パフォーマンスに関する限り、新しいプロセスをフォーク(および実行)するとヒットが発生するため、短い操作では回避する必要があります。ただし、サブプロセスが数秒間実行される場合、それをスピンアップするのにかかる25ms(プレースホルダー#のみ)に気付くことはありません。ただし、非常に高速に実行される一時的な関数があり、頻繁に呼び出す場合は、サブシェルを介して呼び出すと、パフォーマンスが大幅に低下します。

サブプロセスの1つは、コマンドラインから独立してテストできることです。したがって、これらは実際にはスタンドアロンツールであり、これはいくつかの問題に非常に役立ちます。

最後に考慮すべきことが1つあります。「仕事に適したツール」を信じていて、たまたま適切なツールが箱に入っていて、それを実行することで手元のタスクを解決できるのであれば、どうでしょうか。自由に利用できる(そしてすでにインストールされている)ツールによって問題がすでに解決されているため、私の人生で非常に多くのコードを見てきましたが、最終的には無関係でした。たまたま、プログラマーが選択したモノリシック(単一ツールを読み取る)実装環境に適合しませんでした。

当然の結果として、「ハンマーだけを持っているとしたら、すべてが釘のように見えます」ということです。ドライバーに手を伸ばすことを恐れないでください、そして「彼ら全員を支配するための1つのハンマー」カルト主義者に注意してください。

于 2014-03-25T18:16:43.393 に答える