この質問を改善したいですか? この投稿を編集することで、事実と引用で答えられるように質問を更新してください。
クローズド 昨年
今のところ全てのスクリプトは Bash で行っていますが、少し馬鹿げた感じがしてきました。もちろん Bash を使ってやりたいことはすべてできますが (かなり強力です)、代わりに適切なスクリプト言語 (私たちの場合は Ruby) を使うべきではないかと考え始めています
スクリプトにBashよりPerl/Python/Rubyを使うタイミングはどうやって決めていますか?Rubyを使ったinitスクリプトは意味がないと思うのですが、メールアカウントを追加するもう少し長いスクリプトはどうでしょうか?
79 futlib 2012-04-21
どちらも対応できる問題を考えると、自分が最も得意とする方を使いたくなります。最終的には、細かいことはたくさんありますし、それを見ることができるのは経験でしか教えてくれません
Bash は Python, Ruby, Perl と同じように汎用スクリプト言語ですが、それぞれが他の言語とは異なる強みを持っています。Perlはテキスト解析に優れていますし、Pythonはその中でも最もエレガントだと主張していますし、Bashスクリプトは「パイピング」に優れています
しかし、これらの言語の違いは、十分なスクリプティング経験を積んでからでないと意味がありません。次の言語に移る前に、一つの言語を選んで限界までやってみることをお勧めします。シェルスクリプトでは、多くの人が認める以上に多くのことができます。どんな言語でも、あなたが作りたいと思うのと同じくらい難しいものです。シェルスクリプトでいくつかのことを書いた後は、どの言語もあなたにとっては「簡単」なものです
Linux に住んでいるのであれば、シェルに精通していることはすぐに報われます。シェルスクリプトでは解決できない、または現実的ではないタスクを見つけたら、他のものを使ってください
また、シェルスクリプトの学習は非常にシンプルであることを心に留めておいてください。シェルスクリプトの本当の力は、awk, sed, tr, et al.などの他のプログラムにあります
44 mkaito 2012-04-21
TL;DR – bash を使うのは、より良い言語をインストールするときだけにしてください (すでに利用可能な言語がない場合)。コマンドラインでミスなく実行できない場合は、bash/shell でスクリプトを書かないようにしましょう
2015年なので、次のことを考えてみます
memory overhead
- Ruby/Pythonの実行時のメモリオーバーヘッドはbashと比較して(共有ライブラリのため)ごくわずかです
startup time
- Ruby/Pythonの起動は少し遅くなるかもしれませんが、1秒間に100回もタイトなループでRuby/Pythonのフルプロセスを実行することはないでしょう
performance
- ほとんどの典型的なデータクランチはRuby/Pythonで高速になります
- 実行(あるいは生産性)の本当のパフォーマンス/ボトルネックは、ほとんどの場合、”bash/shellを使用しての不足 “になることはありません(スタートアップのためのUbuntuのスイッチングダッシュも、bashが実際に問題であるかを示しています – とbusyboxは、おそらく唯一の使用例です, コードを書いて実行するために’bash’と’vi’以上のものは何もないので、多くの場合、追加/ダウンロードまたは他の何かを保存する方法はありません)
- 他のプロセスを実行して(sed/awk/grep のような)仕事をすることは、実際にはメモリ上のライブオブジェクト上でメソッドを呼び出すよりもはるかに遅いです
productivity
- Ruby/Pythonで “本当の “メソッド、パラメータ、変数、例外を使うのに比べて、Bash/shellでミスをするのはあまりにも簡単です
- アジャイルが主流ですが、Bashはそれをサポートしていません(ユニットテスト機能、ライブラリ、OOO、モジュール性、リンティング、イントロスペクション、ロギング、メタプログラミングに欠けており、何かを壊さずにリファクタリングすることはほぼ不可能)
- 他のシェルとの非互換性が多すぎて、マイナーな環境変数がスクリプトを完全に壊してしまうことがあります(Puppetのような重要な開発者向けツールはshebang行を無視して重要なシェル変数を渡したり書き換えたりします)が、Ruby/Pythonはメジャーなバージョン変更でも比較的スムーズな移行パスが定義されています
- 新しい言語を学ぶことは、シェル固有の問題(特に – 変数名、ブーリアンなし、例外なしなど)のためにシェルスクリプトのデバッグに費やされた時間のほんの一部を代わりに取ります
- スタートアップスクリプトでさえ地雷です(特にシステム起動時に失敗する可能性があるので)、最近のbashのセキュリティ上の欠陥を考えると、プレーンなC(良いライブラリを持つ)を使った方が良いかもしれません
- sed/awk/grepで利用可能なものは何でも、Ruby/Pythonに組み込まれている可能性が高いです – 依存関係やプラットフォーム間でのツールのバージョン間の “違い “はありません(あなたの設定で動作したらどうなるか)
- 職安
- 好きでもない仕事を確保する意味があるのか?(デバッグは大変だけど、つまらないシェルスクリプトのバグを作ることに時間を費やすのが好きな人なら別ですが)
Ruby/Pythonがインストールされていれば、Bash/Shellを使う理由がないことがわかります
また、Ruby/Pythonをインストールしておけば、そもそもbashスクリプトは必要ないでしょう(busyboxを除いて、システムツールの中にはPython/Perlの存在に依存しているものもあります)
そして、シェルスクリプトを書くたびに、より強力で生産的な何かを学ぶのではなく、まさにそれを「練習」していることになります
なぜ最近の人はBashを使うのか?それは恐ろしく、なかなか破れない習慣だからです。スクリプトは最初の数分で「永遠に完成」することはほとんどありません – どんなに人々がそう考えている傾向が強いとしても。このスクリプトの最後のバグだ」という誤謬と一緒です
結論: bash/shellを使うのは絶対にやむを得ないときだけ(~/.bashrc
, busyboxのように) 最近では「仕事に適したツール」というのはほとんどないからです
58 Cezary Baginski 2015-07-04
私はファイルの処理に主眼を置いているときに bash を使います。これには、ファイルの移動、コピー、名前の変更、ファイルを他のプログラムの入力として使用したり、他のプログラムの出力をファイルに保存したりすることが含まれます。実際にファイルの内容を調べたり、ファイルに書き込むための出力を生成したりする bash コードを書くことはほとんどありません
私は、ファイルからデータを読み込み、そのデータを何らかの方法で処理し、出力をファイルに書き込むことに主眼を置いているときは、Perlとpythonを使います。(Perlでは) system
コマンドやバックティック、(pythonでは) subprocess
モジュールをあまりにも広範囲に使っていることに気付いたら、スクリプトをbashで書くことを検討します。一方で、私は時々bashスクリプトに多くの機能を追加し始めることがあり、最終的には、変数のスコープ、関数、データ構造などのbashの限られた(比較的に)サポートに対処するよりも、Perl/pythonで書き直した方が理にかなっています
29 chepner 2012-04-21
私はこのブログ記事で設定された基準が好きです
- 引数がない場合は、おそらくシェルスクリプトでしょう
- 制御ロジックがあまりない場合(シングルループやif/else以外に)は、シェルスクリプトでしょう
- タスクがコマンドライン命令の自動化であれば、ほぼ間違いなくシェルスクリプトです
17 MarkTee 2014-04-09
私はこのPerl対Bashの分析が便利だと思いました
便宜上、その著者の1)bashの方が良い結果が出たときと、2)perlの方が良い結論が出たときの要約をコピーしておきます
バッシュの方が良い時は
- Job Failure
- 終了時のコマンド
- ジョブの出力ラインを処理します
- Here Documents
- File Equivalencies
- ファイルのタイムスタンプの比較
- Tilde Expansion
Perlの方が優れている場合
Perl はほとんどのアプリケーションで bash よりも優れています。私がPerlを好む理由としては、以下のようなものがあります (ただし、これらに限定されません)
- これは高速になります。主に、やりたいことの多くのために、実際に新しいプロセスを開始する必要がないからです(ベースネームとdirnameが最もわかりやすい例ですが、一般的には、cut、grep、sort、およびwcも同様にすべて削除することができます)
- bash での文字列処理はせいぜい初歩的なもので、$IFS 全体が非常に陳腐です
- シェルスクリプトの条件式は変なことがあります
- シェルスクリプトでの引用は悪夢のようなものです
- bash の case 文は、単純なケース (NPI) を超えて、多くのことが望まれています
- bash の配列はクソです。bash のハッシュは(あなたの bash が十分に新しいものであることを前提としていますが)さらに難しくなります
- ファイルの処理やコマンド出力が上記の単純なケースを超えてくると、Perlは本当にbashを吸い始めます
- CPAN.
だから、すぐに bash が Perl に取って代わろうとしているわけではありません。しかし、何年も経った今でも、単純なシェルスクリプトの方が単純なPerlスクリプトよりも単純な場合が多いことに気がつきます。私が言うように、そうでなければ私を納得させようとする試みを歓迎します。しかし、ツールボックスの中にいくつかの異なるツールがあることは何も悪いことではありません
9 buzz3791 2014-04-24
私の経験では、bashとpythonは開発時間と柔軟性のトレードオフです。問題に対する初歩的な解決策は、通常、python スクリプトよりも bash スクリプトの方が早く確立できます
Pythonは、同等のbashスクリプトよりも、ソリューションの構造についてより深く考えさせられる傾向があります。Pythonはbashスクリプトよりも表現力があるので、時間をかけてスケールしたり修正したりする傾向があります。また、一般的にはより読みやすいままです
Bash はファイルシステムに近く、よく定義されていない問題の最初のドラフトソリューションに最適です。このような理由から、bash スクリプトは、問題がよりよく理解されたら python に移植するという完全な意図を持って、何かをプロトタイプ化するための最初の良い選択かもしれません
6 Travis 2015-09-30
BashはUnixシェルで、スクリプト言語を含んでいます。コマンドをどのように実行するかをコントロールし、実際に実行します
Perl/Ruby/Pythonは汎用言語です
シェルスクリプトが欲しいときはBashを使います
もっと複雑な作業をしたい場合や、シェルとは関係のない作業をしたい場合は、Pythonなどを使います。Pythonなどを使う
私はこれらの言語を実際に比較することはありません。Pythonなどは移植性に優れています。どこでも実行できます。BashはUnix専用です
Pythonなどには、何百万ものタスクを解決する再利用可能なライブラリがたくさんあります
聞けばほぼ同じです。”ペイントを使うタイミングとフォトショップを使うタイミング”
メールの処理には、再利用可能なライブラリが多いので、改めてRubyを使うことにしました
でも、一番いいのはbashとrubyを組み合わせることでしょう。そうですね。ruby でメール処理スクリプトを作り、bash スクリプトがその ruby スクリプトを起動して他のコマンドを実行する、というような感じです
ですから、コマンドプロセッサが必要なときはいつでもbashを使います。unixコマンドを実行して、それを制御します
7年ぶりのUPDATE(2019年3月)
私の回答の主な部分は変わりませんでしたが、そのことを指摘しておきたいと思います
Bash は強力なスクリプト言語でもあります。テキスト処理には絶対的な選択肢になるでしょう
以下、mkaitoさんのコメントをお読みください。どれも完全に真実です
4 bakytn 2012-04-21
bash, ksh, zsh, sh, fish のようなシェルスクリプトは、Ruby, Python, Perl のような高レベルの汎用言語と比較して、意外性があることで知られています。シェルスクリプトは、同等の汎用スクリプトよりも短いファイルで始まるかもしれませんが、その驚きは、厳格なモードを有効にするための set -euo pipefail
のような防御的なラッピングコードにつながります
例として、ほとんどのシェル言語は、コマンドの一つが失敗してもシェルスクリプトの行を実行し続けます。対照的に、汎用言語は、最初のエラーが発生したときにすぐに失敗し、多くの場合、負荷がかかるので、結果として、より安全で、より予測可能な動作を実現することができます
1 mcandre 2017-07-09
偏りの強い記事
私はbashがデバッグをするのがそんなに難しいとは思いません。Pythonがあまりにも堅苦しいのに対して、bashは非常にクリエイティブなことができます。もしあなたが既成概念にとらわれない発想が得意なら、bashが好きになるでしょう
私は何千ものファイルの中の何百万ものDNA配列の読み取りでbashスクリプトを実行していますが、それは私にちょうどよく機能しています。そして、誰もが言うことに反して、C++のスクリプトの同じバージョンは、実際にはそれほど速くは実行されません(数分間隔で)
bashはperlのように、最もユーザーフレンドリーで読みやすいものではないと思います。ほとんどの人は抽象的な思考が苦手なので、それが人々を怖がらせています。しかし、より聡明で創造的なプログラマーはbashが好きで、頻繁に使っている傾向があります。自分のことを知っていて、自分の頭脳があることを知っている人は、bashに怖がらないでください。あなたが基本的な思考力を持っているなら、Pythonのようなものに固執するのもいいかもしれません。人それぞれです
1 C K 2017-11-09
ラマの本」より
- Randal L. Schwartz, Tom Phoenix, and brian d foy, Learning Perl (Sebastopol, CA: O’Reilly, 2011), ch.1.2 “Perl は何の略か?”、§”Why Didn’t Larry [the creator of Perl] Just Use Some Other Language?”, p. 5
Perl は、(C や C++ やアセンブリのような)低レベルのプログラミングと(シェルのような)高レベルのプログラミングの間のギャップを埋めようとしています(
bash
など)。低レベルプログラミングは通常、書きにくくて醜いが、高速で無制限であることが多く、与えられたマシン上でよく書かれた低レベルプログラムの速度には勝てない。そして、そこでできないことはほとんどありません。必要な機能を提供するコマンドがシステム上にない場合、シェルやバッチプログラミングでは全くできないことがたくさんあります。必要な機能を提供するコマンドがシステムにない場合は、シェルやバッチプログラミングでは全くできないことがたくさんあります
0 Geremia 2016-09-08
親指のルールとして、手元のタスクに十分な性能を持つ最も単純な言語を使用してください。そして、その特殊性は、それらが本当に有用である範囲内でのみ使用してください
そして読みやすさについてですが、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 "${@}"
0 Alberto Salvia Novella 2019-04-02