Bashを使用する場合とPerl / Python / Rubyを使用する場合 [閉まっている]


78

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

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


1
どちらでも使用できる場合、それは本当に重要ですか?結果のスクリプトに違いがある場合にのみ、選択は興味深いものです。たとえば、実行時間は大幅に異なる可能性があります(電子メールアカウントの場合の問題ではありません)。
デニス

回答:


44

両方が処理できる問題がある場合、最も使いやすいものを使用する必要があります。最終的に、多くの細かい部分があり、経験だけがそれらを見ることができます。

BashはPython、Ruby、Perlのような汎用スクリプト言語ですが、それぞれが他のものとは異なる強みを持っています。Perlはテキスト分析に優れており、Pythonは最も洗練されたものであると主張しています。Bashスクリプトは、「意味のパイプ」に優れています。方法の。

ただし、両者の違いは、十分な量のスクリプティングエクスペリエンスを身に付けて初めて重要になります。1つの言語を選択し、次の言語に移行する前に、その言語を限界までプッシュすることをお勧めします。ほとんどの人が認める以上に、シェルスクリプトで多くのことができます。どんな言語でも、あなたがそれを作りたいと同じくらい難しいです。その中にいくつかのことを書いた後、すべての言語はあなたにとって「簡単」です。

Linuxに住んでいる場合、シェルに精通しているとすぐに報われるので、それから始めたいかもしれません。シェルスクリプトで解決することが不可能または非現実的なタスクを見つけた場合は、別のものを使用してください。

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


Rubyと同様に、bashスクリプトの経験はかなりありますが、何を使うべきかまだわからないことがあります。その瞬間の個人的な好みに基づいて選択することはばかげているようです。しかし、あなたは正しいです、私は自分が何をしたいのか自問し、仕事に最適なツールを選択します。
futlib

個人的には、私がよく知っている言語のスケールを複雑さとパワーの昇順で使用し、法案に適合する最も単純な言語を使用します。しかし、実際には、確実に知る唯一の方法は、すべての言語でスクリプトを記述し、結果を比較することです。それはすべて、確実性というよりもむしろ直感的なものです。数年スクリプトを書いた後、あなたはほとんどの「問題のタイプ」に出会い、どの言語がそれらをうまく解決したかを知っているでしょう。
mkaito

GNU coreutilsパッケージの小さなプログラム(tr、sort、uniqなど)を使用して追加し、それらをパイピングするだけで、多くのタスクを実行できるようになりました。
GMaster

58

TL; DR- より良い言語をインストールする場合にのみ bashを使用します(まだ使用可能でない場合)。間違いなく手作業でコマンドラインで実行できない場合は、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が実際に問題であることが示されます-そして、busyboxがおそらく唯一のユースケースですなぜなら、コードを記述して実行するための「bash」と「vi」以外のものなく、多くの場合、他のものを追加/ダウンロードまたは保存する方法がないためです)
    • ジョブを実行する他のプロセス(sed / awk / grepなど)の実行は、実際にはメモリ内のライブオブジェクトでメソッドを呼び出すよりも非常に遅くなります。
  4. 生産性

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

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

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

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

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

結論:bash / shellは、(たとえばbusyboxなど)絶対に強制されている場合にのみ使用してください。~/.bashrcこれは、今日では「仕事に最適なツール」ではないためです。


28

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

私は、ファイルからデータを読み取り、何らかの方法でそのデータを処理し、出力をファイルに書き込むことに主眼を置いているときに、Perlとpythonを使用します。(Perlで)systemコマンド、バックティック、または(Pythonで)subprocessモジュールを過度に使用していることに気付いた場合は、bashでスクリプトを書くことを検討します。一方、bashスクリプトに非常に多くの機能を追加し始めると、変数スコープ、関数、データ構造などのbashの制限された(比較による)サポートを処理するよりも、最終的にPerl / pythonで書き直す方が理にかなっていることがあります。 。


2
私は、ファイルの読み込み/テキストの生成が必要とされた時はいつでもまたバッシュに保釈T0を使用しますが、学習後=~でサポートされているオペレータ[[ ]]私は私にいくつかのバッシュを愛してきた、単純なファイルの読み込み
Freedom_Ben

16

このブログ投稿に記載されている基準が好きです。

  • 渡す引数がない場合は、おそらくシェルスクリプトです。
  • 制御ロジックがあまりない場合(単一ループまたはif / else以外)は、おそらくシェルスクリプトです。
  • タスクがコマンドライン命令の自動化である場合、それはほぼ間違いなくシェルスクリプトです。

8

このPerl対Bashの分析は便利だと思いました...

http://blogs.perl.org/users/buddy_burden/2012/04/perl-vs-shell-scripts.html

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

Bashの方が良い場合...

  • ジョブ失敗
  • 終了時のコマンド
  • ジョブ出力行の処理
  • ヒアドキュメント
  • ファイルの同値
  • ファイルのタイムスタンプの比較
  • チルダ拡張

Perlの方が良いとき...

ほとんどのアプリケーションでは、Perlは依然としてbashに勝っています。私がPerlを好むかもしれない理由は以下を含みます(しかし、それに限定されません):

  • より速くなるでしょう。主に、やりたいことの多くのために新しいプロセスを実際に開始する必要がないためです(basenameとdirnameは最も明白な例ですが、一般にcut、grep、sort、wcもすべて削除できます)。
  • bashでの文字列処理はせいぜい初歩的なもので、$ IFS全体は非常に扱いにくいものです。
  • シェルスクリプトの条件文は不安定な場合があります。
  • シェルスクリプトで引用するのは悪夢です。
  • bashのcaseステートメントは、単純なケース(NPI)を超える多くの要望を残しています。
  • bashの配列はひどいものです。bashのハッシュ(bashはまったく新しいと仮定して)はさらに激しく吸い込みます。
  • ファイルまたはコマンド出力の処理が上記の単純なケースを超えると、Perlは実際にbashを喫煙し始めます。
  • CPAN。

だから、bashがPerlのためにすぐに引き継ぐつもりはない。しかし、何年も経った今でも、単純なシェルスクリプトは、単純なPerlスクリプトよりも単純な場合が多いことがわかりました。私が言うように、そうでなければ私を説得するあらゆる試みを歓迎します。しかし、それでも、ツールボックスにいくつかの異なるツールを配置しても何も問題はありません。


興味深いことに、Rubyでは、すべての(?)ポイントは適用されません。Rubyにはat_exit()、realpath()、expand_path()、stat()、heredocs、およびexceptions(fail "error" unless system("foobar"))があるためです。
セザリーバギンスキー

5

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

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

Bashはファイルシステムにより近く、明確に定義されていない問題の最初のドラフトソリューションに最適です。このため、問題の理解が深まったら、Pythonに移植するという完全な意図を持って、bashスクリプトを試してみるのがよいでしょう。


4

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

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

シェルスクリプトが必要な場合は、Bashを使用します

より複雑なタスクが必要な場合、またはシェルに関連しない場合。Pythonなどを使用します

これらの言語を実際に比較することは決してありません。Pythonなどは移植可能です。どこでも実行できます。BashはUnix専用です。

Pythonなどには、何百万ものタスクを解決する再利用可能なライブラリがたくさんあります。

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

電子メールの処理には、再利用可能なライブラリが多数あるため、Rubyを使用します。

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

したがって、コマンドプロセッサが必要な場合は常にbashを使用します。UNIXコマンドを実行して制御します。

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

私の答えの大部分は変わらなかったが、それを指摘したい。

Bashは強力なスクリプト言語でもあります。テキスト処理の場合は、絶対に正当な選択が可能です。

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


1
Bashのスクリプトサブセットは、汎用スクリプト言語と同様に汎用です。sedのような一般的なプログラムをミックスに追加すれば、これまでにないすべてのスクリプト作成ニーズの90%をカバーできます。
mkaito

1
そのパワーは、他のUNIXは、あなたは彼が特定の言語を選択するときのために求めているなどのsed述べた彼らのscripts.likeにコマンドやプログラムを実行することですので、bashはコマンドプロセッサである
bakytn

1
シェルは確かに栄光に満ちたプログラムランチャーですが、スクリプト機能はそれをはるかに超えています。実際のシェルスクリプトを学ぶことをお勧めします。
mkaito

私は床で眠ることができますが、私はむしろベッドでそれをしたいです。これらの言語は、目的が異なるため比較できません。
bakytn

2
まあ、Bashが床なら、Haskellのようなものはネイルボードでなければなりません:-)
mkaito

1

bash、ksh、zsh、sh、fishな​​どのシェルスクリプトは、Ruby、Python、Perlなどの高レベルの汎用言語と比較して驚くほど驚くべきことです。シェルスクリプトは、同等の汎用スクリプトよりも短いファイルとしてその寿命を開始する可能性がありますが、驚きはset -euo pipefail厳格なモードを有効にするなど、多くの防御的なラッピングコードにつながります。

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


1

非常に偏った記事。

bashをデバッグするのはそれほど難しいとは思いません。Pythonは非常に硬直していることがよくありますが、bashを使用すると非常にクリエイティブになります。あなたがすぐに使える思想家であれば、bashが好きになるでしょう。

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

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


0

「Llama Book」から

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


0

経験則として、手元のタスクに十分なパフォーマンスを発揮する最も単純な言語を使用します。そして、その特殊性は、それらが本当に有用である限りにおいてのみです。

読みやすさについては、プログラミングスタイルがひどい場合、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 "${@}"
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.