web-dev-qa-db-ja.com

多くのif-elseステートメントとforループを含むシェルスクリプトを書くのは悪い習慣ですか?

私は、if-elseステートメントとforループでいっぱいのいくつかのデータプロセスシェルスクリプトを維持しています。スクリプトを整理してデバッグしやすいものにするようにしています。

シェルコードのベストプラクティスに関するいくつかの提案を読んだとき、多くのif-elseおよびforループステートメントを使用することはベストプラクティスではないようです。

では、これらの論理プロセスの代わりにpythonまたはc ++スクリプトを作成するにはどうすればよいですか?

3
xiao

埋め込み if/elseまたはループが多すぎることは決して良い考えではありませんが、それ自体では、多くは本質的に悪いことではありません。

ループをユーティリティ関数に分割することを検討してください。たとえば、次の場合:

for stuff ..
   for stuff ...

   endfor
endfor

それは次のように読む方がはるかに良いでしょう

findAllPricesForProducts( extractNamePriceTuple( data ) )

効用関数が適切に定義されています。次に、各関数を文書化し、入出力の例を示すと、コードは読み取り可能で保守可能である必要があります。

4
Jay

Perlコーダー(これはPythonに簡単に調整できます)として、私は「10行より長いシェルスクリプトはすべてPerlスクリプトでなければならない」と言ったのを聞いたことがあります。サイズ/複雑さの特定のしきい値を超えるシェルスクリプトは、維持するのが悪夢になることがよくあります。優先するスクリプト言語に切り替えると、これを大幅に簡素化できます(そして、grep、awk、sed(または他のあまり知られていないアプリケーション)の繰り返し呼び出しを使用する必要がなくなります。

言語の選択はさておき、私が聞いた別のコメントは、「関数がその機能を説明するために「単語」と「単語」を必要とする場合、それは大きすぎる/複雑すぎる」というものです。ネストされたステートメントがあることは問題ではありませんが、ステートメントの周りのロジックが複雑になった場合は、その一部を抽出して、デバッグ中に頭に入れて、の機能を簡単にテストできるようにすることを検討する必要があります。それ。

3
user40980

シェルスクリプトでifステートメントとforステートメントを使用しても問題はありません。コードは多くのif/forステートメントに深くネストされていますか?

保守性のためにコードをよりモジュール化するために、シェル言語にはユーザー定義関数があることを忘れないでください。

2
glenn jackman

複雑なシェルスクリプトを書くことに反対する主な論拠は、それらはデバッグが難しく、壊れやすいということです。とは言うものの、同じ方法論を別の言語に取り入れても改善にはなりません。あなたがしていることが他のプログラムの束をつなぎ合わせているのであれば、それはほとんど本質的なことです。

1
ddyer

他の言語と同じように...

  • 同じロジックを2回以上記述しないようにしてください
    • たぶん、多くのif-thenステートメントを含むスクリプトをいくつかの関数に減らすことができます。
  • ループ(do、for、while、repeat、until)は、その性質上、半自己完結型のエンジンです。それらは、複雑な機械の電気モーターに類似しています。それらのエラーは、ほぼ普遍的に、すべての「フリーズ」、「ロックアップ」、「100%CPU」および同様の壊滅的なバグの原因です。
    • 慎重に使用してください。同じようなループを複数持つことは絶対にしないでください。コードを「生成」して、同じループを関数に入れ、さまざまな変数や条件で再利用できるようにします。 (「i」(目)であるはずの「l」(el)変数を確認するのに何日もかかった人から)
0
DocSalvager

pythonのような言語でスクリプトを書き直す必要がある場合は、

  • コードの行数を含むスクリプトの数

  • 近い将来に追加されると予想される新しい要件の数(ない場合は、なぜわざわざするのですか?)

  • 彼らが本当にどれほど厄介であるか

  • 新しいバグを導入することなく、それらを本当にうまく実装できると確信していること

そして、書き換えを行う前に、あなたの場合のように小さなものであっても、読んでください ジョエル・スポルスキーのこの有名な記事 なぜ書き換えがしばしば悪い選択であるのか。

0
Doc Brown