web-dev-qa-db-ja.com

いつBashを使い、いつPerl / Python / Rubyを使うのですか?

私たちはこれまでBashを使ってスクリプトを作成してきましたが、私はそれについて少しばかげたことを感じ始めています。もちろん、Bashで必要なことはすべて実行できます(非常に強力です)が、代わりに適切なスクリプト言語(この場合はおそらくRuby)を使用しないでください。

スクリプトにPerl/Python/Ruby over Bashをいつ使用するかをどのように決定しますか? Rubyを使ったinitスクリプトは理にかなっていないと思いますが、電子メールアカウントを追加する少し長いスクリプトについてはどうでしょうか。

76
futlib

どちらにも対処できる問題がある場合は、最も快適なものを使用することをお勧めします。最終的には、細部がたくさんあり、それらを見るように経験できるのは経験だけです。

Bashは、Python、Ruby、Perlのような汎用のスクリプト言語ですが、それぞれの点で長所が異なります。 Perlはテキスト分析に優れています。Pythonは最もエレガントであると主張しています。Bashスクリプトは、私が何を言っているのかわかっていれば「ものを流す」のに優れています方法の。

しかし、それらの違いは、あなたが自分の頭の下で十分な量のスクリプト経験を積んだ後に初めて本当に重要になります。次の言語に進む前に、1つの言語を選択してそれを限界までプッシュすることをお勧めします。シェルスクリプトでは、ほとんどの人が認めている以上に多くのことを実行できます。どんな言語でもあなたがそれを作りたいのと同じくらい難しいです。あなたがその中にいくつかのことを書いた後、すべての言語はあなたにとって「簡単」です。

あなたがLinuxに住んでいるならシェルに慣れていることはすぐに利益を得るので、多分あなたはそれから始めたいと思うでしょう。 Shellスクリプトで解決することが不可能または不可能なタスクを見つけた場合は、別のものを使用してください。

また、シェルスクリプトの習得は非常に簡単です。その真の力は、awk、sed、trなどの他のプログラムにあります。

42
mkaito

TL; DR-より良い言語をインストールするためにbash onlyを使用します(まだ使用できない場合)。そうしないと、回復不能で貴重な時間を無駄にしています。間違いなく手作業でコマンドラインで実行できない場合は、bash/Shellでスクリプトを作成しないでください。

2015年なので、次のことを検討します。

  1. メモリオーバーヘッド

    • Bashと比較したRuby/Pythonランタイムメモリのオーバーヘッドは小さい(共有ライブラリのため)が、とにかく非自明なbashスクリプトを維持できない(つまり、100行を超える)ので、メモリ使用量は要因ではない
  2. 起動時間

    • Ruby/Pythonの起動は少し遅いかもしれませんが、1秒あたり100回のタイトなループで多くの完全なRuby/Pythonプロセスを実行しない可能性があります(そのようなニーズがある場合、bash/Shellはとにかくオーバーヘッドが大きすぎるので、おそらくC/C++にドロップする必要があります)
  3. 性能

    • ほとんどすべての典型的なデータ処理は、Ruby/Pythonで高速になります-または少なくとも同等(または、とにかくC/C++/Haskel/OCaml /何でも必要です)
    • 実行時の実際のパフォーマンス/ボトルネック(または生産性)は、ほとんど決してない「bash/Shellの使用の欠如」になります(起動時のUbuntuスイッチングダッシュでも、bashが実際に問題であることが示されます) isコードを記述して実行するための「bash」と「vi」以外のものはないため、busyboxが唯一のユースケースです。
    • 他のプロセスを実行してジョブを実行する(sed/awk/grepなど)は、実際にはメモリ内のライブオブジェクトでメソッドを呼び出すよりもかなり遅い
  4. 生産性

    • ruby/Pythonで「実際の」メソッド、パラメーター、変数、例外を使用する場合と比較して、Bash/Shellで間違いを犯すのは簡単すぎる
    • アジャイルは主流ですが、Bashはそれをサポートしていません(ユニットテスト機能、ライブラリ、オブジェクト指向、モジュール性、リント、イントロスペクション、ロギング、メタプログラミングに欠けています;何かを壊さずにリファクタリングすることはほとんど不可能です)
    • 他のシェルとの非互換性が多すぎると、マイナーな環境変数がスクリプトを完全に破壊する可能性があります(Puppetなどのいくつかの重要なdev-opsツールはシェバン行を無視して重要なシェル変数を渡したり、書き換えたりします)メジャーバージョンの変更でもパス
    • 新しい言語の学習には、シェル固有の問題(特に、変数名、ブール値、例外なしなど)のためにシェルスクリプトのデバッグに費やす時間の数分の一しかかかりません
    • スタートアップスクリプトでさえ地雷であり(特にsystemスタートアップ中に失敗する可能性があるため)、また、bashの最近のセキュリティ上の欠陥を考えると、プレーンCを使用する方が良いかもしれません(良いライブラリ)-はい、Cはコンパイル、構成などを必要としますが、単純なシェルスクリプトでさえリポジトリ、バージョン管理、パッケージ化が必要な場合があります。
    • sed/awk/grepで利用できるものはすべて、おそらくRuby/Pythonに既に組み込まれています-依存関係になったり、プラットフォーム間でこれらのツールのバージョン間で「相違」があったりします(つまり、yourセットアップ)
  5. 雇用保障
    • 嫌いな仕事を確保する意味は何ですか? (デバッグするのは難しいが作成するのは簡単なシェルスクリプトのバグをすべての時間を費やすのが好きでない限り)

Ruby/Pythonがインストールされている場合、Bash/Shellを使用する理由はないと思います。

そしておそらく、Ruby/Pythonをインストールするのにそもそもbashスクリプトさえ必要ありません(busyboxを除き、一部のシステムツールはPython/Perlが存在することに依存しています)。

そして、シェルスクリプトを記述するたびに、より強力で生産的な何かを学ぶのではなく、まさにそれを「練習」しています。

なぜ人々は最近Bashを使用するのですか?それはひどい、壊れにくい習慣だからです。スクリプトが最初の数分後に「永遠に終了」することはめったにありません-人々がそのように強く考える傾向があるとしても。 「このスクリプトの最後のバグです」という誤解とともに。

結論:絶対にforced to(~/.bashrc、busyboxなど)の場合にのみbash/Shellを使用します。これは、ほとんどnever "仕事に適したツールだからです。 「最近。

57
Cezary Baginski

私の主な焦点がファイル処理にあるとき、私はbashを使います。これには、ファイルの移動、コピー、名前変更、他のプログラムへの入力としてのファイルの使用、または他のプログラムの出力をファイルに格納することなどが含まれます。実際にファイルの内容を調べたり、ファイルに書き込むための出力を生成するbashコードを書くことはめったにありません。私はそれを私がbashを介して起動する他のプログラム(私はPerlまたはpythonで書くことができる)に任せます。

私の主な焦点がファイルからのデータの読み取り、何らかの方法でのそのデータの処理、そしてファイルへの出力の書き込みにあるとき、私はPerlとpythonを使います。 (Perlでは)systemコマンド、バックティック、(Pythonでは)subprocessモジュールを使いすぎた場合は、スクリプトをbashで書くことを検討してください。その一方で、私は時々bashの変数スコープ、関数、データ構造などの限定的なサポートを扱うよりもむしろPerl/pythonでそれを書き直すほうが理にかなっているのでbashスクリプトにそれほど多くの機能を追加し始める。

28
chepner

私はこのブログ記事で を設定した基準を気に入っています

  • 渡す引数がない場合は、おそらくシェルスクリプトです。
  • 制御ロジックにそれほど多くない場合(単一ループやif/else以外)、それはおそらくシェルスクリプトです。
  • タスクがコマンドライン指示の自動化であれば、ほぼ間違いなくシェルスクリプトです。
16
MarkTee

私はこのPerl対Bashの分析が便利だと思った….

http://blogs.Perl.org/users/buddy_burden/2012/04/Perl-vs-Shell-scripts.html

便宜上、私はその作者の要約をコピーします。1)bashがより良い発見であるとき、そして2)Perlがより良い結論であるとき...

Bashが優れていると….

  • 仕事の失敗
  • 終了時のコマンド
  • ジョブ出力行の処理
  • こちらのドキュメント
  • ファイルの等価性
  • ファイルタイムスタンプの比較
  • チルド展開

Perlが優れていると….

Perlは、ほとんどのアプリケーションでいまだに破産品を破っています。私がPerlを好む理由は次のとおりです(ただし、これらに限定されません)。

  • 早くなるでしょう。主に、自分がやりたいことの多くに対して新しいプロセスを開始する必要がないためです(basenameとdirnameは最も明白な例ですが、一般にcut、grep、sort、およびwcもすべて削除できます)。
  • Bashでの文字列処理はせいぜい初歩的なもので、$ IFS全体のことは非常に不格好です。
  • シェルスクリプトの条件文は不思議です。
  • シェルスクリプトでの引用は悪夢になる可能性があります。
  • bashのcase文は単純な場合(NPI)を超えて望まれるべき多くを残します。
  • Bashの配列は吸います。 bashのハッシュ(あなたのbashがまったく新しいものであると仮定した場合)はさらに強く吸います。
  • ファイルやコマンド出力の処理が、上でリストした単純なケースを超えると、Perlは本当にたばこを吸い始めます。
  • CPAN.

それで、bashがいつかPerlに取って代わることにはなりません。しかし、私は、これらすべての年を経ても、単純なシェルスクリプトの方が単純なPerlスクリプトよりも単純な場合が多いことを今でも認識しています。私が言うように、私はそうでなければ私を納得させるすべての試みを歓迎します。それでも、ツールボックスにいくつかの異なるツールを配置しても問題ありません。

8
buzz3791

私の経験では、bash対pythonは開発時間と柔軟性の間のトレードオフです。問題に対する初歩的な解決策は、通常、bashスクリプトではpythonスクリプトよりも早く確立できます。

Pythonでは、同等のbashスクリプトよりも自分のソリューションの構造について考えさせられる傾向があります。 Pythonはbashスクリプトより表現力があるため、時間の経過とともにスケールと変更が改善される傾向があります。また、一般的に読みやすくなっています。

Bashはファイルシステムにより近く、明確に定義されていない問題に対する最初のドラフトソリューションに最適です。このため、問題がよく理解されたら、bashスクリプトをpythonに移植することを完全に意図して、何かをプロトタイプで作成することをお勧めします。

5
Travis

Bashはスクリプト言語を含むUnixシェルです。むしろコマンドプロセッサです。あなたはコマンドの実行方法を制御し、実際にそれらを実行します。

Perl/Ruby/Pythonは汎用言語です。

シェルスクリプトが欲しいときは、Bashを使います。

もっと複雑な作業が必要な場合や、Shellに関連していない場合。 Pythonなどを使う.

私は実際にこれらの言語を比較することは決してないでしょう。 Pythonなどは移植可能です。あなたはどこでもそれらを実行することができます。 BashはUnix専用です。

Pythonなどには、何百万というタスクを解決する大量の再利用可能なライブラリがあります。

あなたが尋ねればそれはほとんど同じです。 「ペイントを使用する場合とPhotoshopを使用する場合」

電子メールを処理するために、私はRubyを使用することにしました。再利用可能なライブラリがたくさんあるからです。

しかし最良の方法はbashとRubyを組み合わせることでしょう。それは正しいでしょう。あなたがRubyで電子メール処理スクリプトを作成するように、bashスクリプトはそのRubyスクリプトを呼び出して他のコマンドを実行します。

そのため、コマンドプロセッサが必要なときはいつでもbashを使用します。あなたはunixコマンドを実行してそれらを制御します。

7年後の更新(2019年3月)

私の答えの大部分は変わっていませんが、私はそれを指摘したいと思います。

Bashも強力なスクリプト言語です。テキスト処理のためにそれは絶対的な合法的な選択かもしれません。

以下のmkaitoのコメントを読んでください。それらはすべて完全に真実です。

4
bakytn

Bash、ksh、zsh、sh、およびfishな​​どのシェルスクリプトは、Ruby、Python、またはPerlなどの高水準汎用言語と比較して、驚くほど驚くべきものです。シェルスクリプトは同等の汎用スクリプトよりも短いファイルとして寿命を迎えるかもしれませんが、驚いたことに、厳密なモードを有効にするためのset -euo pipefailのような多くの防御的なラッピングコードが生まれます。

たとえば、ほとんどのシェル言語は、コマンドの1つが失敗した場合でも、シェルスクリプト内で行を実行し続けます。これとは対照的に、汎用言語は最初のエラーですぐに失敗し、多くの場合非常に負荷がかかります。その結果、スクリプトの安全性と予測可能性がさらに複雑になります。

1
mcandre

偏った記事.

Bashをデバッグするのがそれほど難しいとは思いません。 bashはあなたが非常に創造的であることを可能にしているのに対し、Pythonはしばしばあまりにも堅いです。すぐに使える優れた思想家なら、bashが好きです。

私は何千ものファイルの何百ものDNAシーケンス読み取りに対してbashスクリプトを実行しました、そしてそれは私に大いに役立ちます。そして、誰もが言っていることとは反対に、C++の同じバージョンのスクリプトは、実際にはそれほど速くは実行されません(数分で分離されます)。

Perlのように、bashは最もユーザーフレンドリーで読みやすいものではないと思います。ほとんどの人は偉大な抽象思想家ではないので、それは人々を怖がらせます。しかし、より明るく、より創造的なプログラマーはそれを愛し、それを頻繁に利用する傾向があります。あなたがあなた自身を知っていて、あなたがあなたが脳を持っていることを知っているならば、bashによって怖がってはいけません。もしあなたが基本的な思想家なら、おそらくPythonのようなものに固執するでしょう。それぞれ独自に。

1
C K

経験則として、当面のタスクに十分なパフォーマンスを持つ最も簡単な言語を使用してください。そして、その特殊性は、それらが本当に有用であるという範囲だけに広がります。

そして読みやすさについては、Bashはあなたのプログラミングスタイルがひどい場合にはひどいものです。あなたがただあそこにコードを投げると、それはあいまいになります。

しかし、コードを最短の関数に分割し、わかりやすい方法で名前を付けると、最もわかりやすい言語になります。とても簡潔ですから。

見本として、これは私の最新のBashコードです。理解しやすく入力するのがいかに簡単かに注目してください。

#! /bin/bash


mainFunction () {
    file="${1}"

    checkFile "${file}"
    executeFile "${file}"
}


changeToThisProgramDir () {
    cd "$( dirname "${BASH_SOURCE[0]}" )"
}


checkFile () {
    file="${1}"

    checkFileNotEmpty "${file}"
    checkFileExist "${file}"
    checkFileIsExe "${file}"
}


checkFileExist () {
    file="${1}"

    if [ ! -f "${file}" ]; then
        echo "The file doesn't exist: ${file}" >&2
        echo "If the name was correct either type: exeCute \"pathToYourExeFile\""
        echo "Or just open with exeCute from the file manager"
        exit 1
    fi
}


checkFileIsExe () {
    file="${1}"
    mime=$(fileMime "${file}")

    if [ "${mime}" != "application/x-dosexec" ]; then
        echo "Not an exe: ${file}" >&2
        exit 1
    fi
}


checkFileNotEmpty () {
    file="${1}"

    if [ "${file}" == "" ]; then
        echo "No file specified" >&2
        echo "Either type this: exeCute \"pathToYourExeFile\""
        echo "Or just open with exeCute from the file manager"
        exit 1
    fi
}


execute () {
    function="${1}"
    command="${2}"
    error=$(eval "${command}" 2>&1 >"/dev/null")

    if [ ${?} -ne 0 ]; then
        echo "${function}: ${error}" >&2
        exit 1
    fi
}


executeFile () {
    file="${1}"
    type=$(fileType "${file}")

    if [ "${type}" == "MS-DOS executable" ]; then
        execute "executeFile" "dosbox \"${file}\" -forcescaler normal2x -exit -fullscreen"
    else
        execute "executeFile" "wine \"${file}\""
    fi
}


fileMime () {
    file="${1}"

    attributes=$(file --brief --mime "${file}")
    IFS=";" read -r -a attributes <<< "${attributes}"
    echo "${attributes[0]}"
}


fileType () {
    file="${1}"

    attributes=$(file --brief "${file}")
    IFS="," read -r -a attributes <<< "${attributes}"
    echo "${attributes[0]}"
}


changeToThisProgramDir
mainFunction "${@}"

「ラマ書」より

Perlは、低レベルプログラミング(C、C++、アセンブリなど)と高レベルプログラミング(「シェル」プログラミング[bash]など)との間のギャップを埋めようとします。低レベルのプログラミングは通常書くのが難しく醜いですが、速く無制限です。特定のマシン上でよく書かれた低レベルのプログラムの速度を超えるのは難しいです。そんなことできないことはあまりありません。それとは反対に、高水準プログラミングは遅く、困難で、見苦しく、そして制限される傾向があります。必要な機能を提供するコマンドがシステムにない場合、シェルまたはバッチプログラミングではまったくできないことがたくさんあります。 Perlは簡単で、ほぼ無制限で、ほとんどが高速で、そして醜いものです。

0
Geremia