Wann soll Bash und wann Perl / Python / Ruby verwendet werden? [geschlossen]

78

Wir machen alle unsere Skripte bisher mit Bash, aber ich fange an, mich ein bisschen albern darüber zu fühlen. Obwohl wir mit Bash natürlich alles machen können, was wir wollen (es ist ziemlich mächtig), frage ich mich, ob wir nicht stattdessen eine richtige Skriptsprache verwenden sollten (in unserem Fall höchstwahrscheinlich Ruby).

Wie entscheiden Sie, wann Sie Perl / Python / Ruby über Bash für ein Skript verwenden? Ich denke nicht, dass ein Init-Skript mit Ruby Sinn macht, aber wie wäre es mit einem etwas längeren Skript, das E-Mail-Konten hinzufügt?

futlib
quelle
1
Wenn Sie es mit einer der beiden Methoden schaffen, spielt es dann wirklich eine Rolle? Die Auswahl ist nur dann interessant, wenn das resultierende Skript Unterschiede aufweist. Beispielsweise kann sich die Ausführungszeit drastisch unterscheiden (kein Problem bei E-Mail-Konten).
Dennis

Antworten:

44

Angesichts eines Problems, mit dem beide umgehen können, sollten Sie das verwenden, mit dem Sie sich am wohlsten fühlen. Letztendlich gibt es viele kleine Details, und nur Erfahrung kann Sie lehren, sie zu sehen.

Bash ist eine Allzweck-Skriptsprache wie Python, Ruby und Perl, aber jede hat andere Stärken als der Rest. Perl ist hervorragend in der Textanalyse, Python behauptet, das eleganteste der ganzen Reihe zu sein, Bash-Skripte eignen sich hervorragend zum "Umleiten", wenn Sie wissen, was ich meine, und Ruby ... nun, Ruby ist in vielen Dingen etwas Besonderes Von Wegen.

Die Unterschiede zwischen ihnen sind jedoch nur dann von Bedeutung, wenn Sie über ausreichend Erfahrung mit Skripten verfügen. Ich schlage vor, dass Sie eine Sprache auswählen und an ihre Grenzen gehen, bevor Sie zur nächsten wechseln. In einem Shell-Skript kann man viel machen, mehr als die meisten Leute zugeben würden. Jede Sprache ist so schwer, wie Sie es wollen. Nachdem Sie ein paar Dinge geschrieben haben, ist jede Sprache für Sie "einfach".

Mit der Shell vertraut zu sein, zahlt sich schnell aus, wenn Sie unter Linux leben. Vielleicht möchten Sie damit beginnen. Wenn Sie in einem Shell-Skript eine Aufgabe finden, die Sie unmöglich oder unpraktisch lösen können, verwenden Sie etwas anderes.

Denken Sie auch daran, dass das Erlernen von Shell-Skripten sehr einfach ist. Die eigentliche Stärke liegt in anderen Programmen wie awk, sed, tr, et al.

mkaito
quelle
Ich habe ziemlich viel Erfahrung mit Bash-Skripten wie mit Ruby, aber manchmal weiß ich immer noch nicht, was ich verwenden soll. Die Wahl auf der Grundlage persönlicher Vorlieben zu diesem Zeitpunkt scheint dumm zu sein. Aber du hast recht, ich frage mich, was ich tun möchte und wähle das beste Werkzeug für den Job aus.
Futlib
Persönlich verwende ich eine Skala der Sprachen, die ich gut kenne, in aufsteigender Reihenfolge von Komplexität und Leistung, und verwende die einfachste, die der Rechnung entspricht. Aber die einzige Möglichkeit, dies sicher zu wissen, besteht darin, Ihr Skript in allen Sprachen zu schreiben und das Ergebnis zu vergleichen. Es ist eher ein Bauchgefühl als eine Gewissheit. Nach einigen Jahren des Schreibens von Skripten sind Sie auf die meisten "Arten von Problemen" gestoßen und wissen, welche Sprache sie gut gelöst hat.
Mkaito
Ich wollte nur hinzufügen, dass mit kleinen Programmen im GNU-Paket coreutils (wie tr, sort, uniq) und deren Weiterleitung viele Aufgaben erledigt werden können.
GMaster
58

TL; DR - Verwenden Sie bash nur, um eine bessere Sprache zu installieren (sofern diese noch nicht verfügbar ist), andernfalls verschwenden Sie nicht behebbare, kostbare menschliche Zeit. Wenn Sie es nicht ohne Fehler von Hand auf der Kommandozeile machen können, schreiben Sie nicht mit bash / shell.

Es ist 2015, daher würde ich Folgendes in Betracht ziehen:

  1. Speicheraufwand

    • Der Speicheraufwand für die Ruby / Python-Laufzeit im Vergleich zu Bash ist gering (aufgrund der gemeinsam genutzten Bibliotheken), während ein nicht triviales Bash-Skript (dh eines mit mehr als 100 Zeilen) wahrscheinlich ohnehin nicht verwaltet werden kann
  2. Startzeit

    • Der Start von Ruby / Python ist zwar ein bisschen langsamer, aber es ist wahrscheinlich, dass Sie nicht 100-mal pro Sekunde viele vollständige Ruby / Python-Prozesse in einer engen Schleife ausführen (wenn Sie solche Anforderungen haben, ist bash / shell dies sowieso zu viel Aufwand und Sie müssen wahrscheinlich auf C / C ++ fallen)
  3. Performance

    • In Ruby / Python sind fast alle typischen Datenverknüpfungen schneller - oder zumindest vergleichbar (oder Sie benötigen ohnehin C / C ++ / Haskel / OCaml / was auch immer).
    • Die tatsächliche Leistung / der tatsächliche Engpass bei der Ausführung (oder sogar die Produktivität) wird so gut wie nie "ein Mangel an bash / shell" sein , denn es ist nichts anderes als ‚bash‘ und ‚vi‘ zu schreiben und Code ausführen, und es gibt oft keine Möglichkeit zum hinzufügen / Download oder speichern von irgendetwas anderes)
    • Das Ausführen anderer Prozesse (wie sed / awk / grep) ist tatsächlich um ein Vielfaches langsamer als das Aufrufen einer Methode für ein Live-Objekt im Speicher
  4. Produktivität

    • Es ist zu einfach, Fehler in Bash / Shell zu machen, als "echte" Methoden, Parameter, Variablen und Ausnahmen in Ruby / Python zu verwenden
    • Agile ist Mainstream, während Bash keine Unterstützung dafür hat (fehlende Unit-Test-Funktionen, Bibliotheken, OO, Modularität, Flusen, Introspektion, Protokollierung, Metaprogrammierung; fast unmöglich zu überarbeiten, ohne etwas zu beschädigen)
    • Zu viele Inkompatibilitäten mit anderen Shells führen dazu, dass kleinere Umgebungsvariablen ein Skript vollständig beschädigen (und einige wichtige Entwicklungswerkzeuge wie Puppet ignorieren die Shebang-Zeilen und geben wichtige Shell-Variablen weiter oder schreiben sie neu), während Ruby / Python eine gut definierte, relativ reibungslose Migration aufweisen Pfade auch für größere Versionsänderungen
    • Das Erlernen einer neuen Sprache nimmt einen Bruchteil der Zeit in Anspruch, die das Debuggen von Shell-Skripten aufgrund von Shell-spezifischen Problemen (insbesondere Variablennamen, keine Booleschen Werte, keine Ausnahmen usw.) erfordert.
    • Selbst Startskripte sind eine Landmine ( insbesondere, weil sie während des Systemstarts fehlschlagen können ). Angesichts der jüngsten Sicherheitslücken bei bash ist es möglicherweise besser, einfaches C (mit guten Bibliotheken) zu verwenden - ja, C muss kompiliert, konfiguriert usw. werden. Aber selbst ein einfaches Shell-Skript benötigt möglicherweise ein Repository, eine Versionsverwaltung und ein Paket.
    • Was auch immer mit sed / awk / grep verfügbar ist, ist wahrscheinlich bereits in Ruby / Python integriert - ohne dass es eine Abhängigkeit oder "Unterschiede" zwischen den Versionen dieser Tools auf verschiedenen Plattformen gibt (was ist, wenn es in Ihrem Setup funktioniert )
  5. Berufssicherheit
    • Was nützt es, sich einen Job zu sichern, den Sie nicht mögen? (es sei denn, Sie verbringen all diese Stunden mit schwer zu debuggenden, aber trivial zu erstellenden Shell-Skript-Fehlern)

Ich finde, es gibt keinen Grund, Bash / Shell zu verwenden, wenn Ruby / Python installiert ist.

Und wahrscheinlich wird für die Installation von Ruby / Python nicht einmal ein Bash-Skript benötigt (mit Ausnahme von busybox sind einige System-Tools ohnehin davon abhängig, dass Python / Perl vorhanden ist).

Und jedes Mal, wenn Sie ein Shell-Skript schreiben, "üben" Sie genau das - anstatt etwas Mächtigeres / Produktiveres zu lernen.

Warum benutzen die Leute heutzutage Bash? Weil es eine schreckliche Angewohnheit ist, die sich nur schwer auflösen lässt. Ein Drehbuch ist selten nach den ersten Minuten "für immer" fertig - egal wie stark die Leute dazu neigen, so zu denken. Zusammen mit dem Irrtum "Es ist der letzte Fehler in diesem Skript".

Fazit: Verwenden Sie bash / shell nur, wenn Sie absolut dazu gezwungen sind (z. B. ~/.bashrcbusybox), da es heutzutage fast nie mehr das "richtige Werkzeug für den Job" ist.

Cezary Baginski
quelle
28

Ich benutze bash, wenn mein Hauptaugenmerk auf der Dateiverwaltung liegt. Dies kann das Verschieben, Kopieren und Umbenennen von Dateien sowie das Verwenden von Dateien als Eingabe für andere Programme oder das Speichern der Ausgabe eines anderen Programms in Dateien umfassen. Ich schreibe selten Bash-Code, der den Inhalt einer Datei untersucht oder die Ausgabe zum Schreiben in eine Datei generiert. Das überlasse ich den anderen Programmen (die ich in Perl oder Python schreiben kann), die ich über bash starte.

Ich verwende Perl und Python, wenn mein Hauptaugenmerk auf dem Lesen von Daten aus Dateien, der Verarbeitung dieser Daten und dem Schreiben von Ausgaben in Dateien liegt. Wenn ich (in Perl) das systemKommando, Back Ticks oder (in Python) das subprocessModul zu ausführlich benutze , denke ich darüber nach, das Skript in bash zu schreiben. Andererseits fange ich manchmal an, einem Bash-Skript so viel Funktionalität hinzuzufügen, dass es irgendwann sinnvoller ist, es in Perl / Python neu zu schreiben, als mich mit der (im Vergleich) eingeschränkten Unterstützung von Bash für Variablenbereiche, Funktionen, Datenstrukturen usw. Zu befassen .

chepner
quelle
2
Ich habe t0 auch verwendet, um auf Bash zu sparen, wann immer das Lesen von Dateien / das Generieren von Text erforderlich war, aber nach dem Erlernen des =~von [[ ]]mir unterstützten Operators habe ich mich für ein
bisschen
16

Ich mag die Kriterien in diesem Blog-Beitrag .

  • Wenn keine Argumente übergeben werden müssen, handelt es sich wahrscheinlich um ein Shell-Skript.
  • Wenn es für die Steuerlogik nicht viel gibt (außer einer einzelnen Schleife oder if / else), ist es wahrscheinlich ein Shell-Skript.
  • Wenn die Aufgabe die Automatisierung von Befehlszeilenanweisungen ist, handelt es sich mit ziemlicher Sicherheit um ein Shell-Skript.
MarkTee
quelle
8

Ich fand diese Perl versus Bash Analyse nützlich ...

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

Der Einfachheit halber kopiere ich eine Zusammenfassung des Autors 1) wenn Bash bessere Ergebnisse liefert und 2) wenn Perl bessere Ergebnisse liefert ...

Wenn Bash besser ist ...

  • Auftragsfehler
  • Befehle beim Beenden
  • Job-Ausgabezeilen verarbeiten
  • Hier Dokumente
  • Dateiäquivalenzen
  • Datei-Zeitstempel-Vergleiche
  • Tilde-Erweiterung

Wenn Perl besser ist ...

Perl schlägt bei den meisten Anwendungen immer noch die Nase voll. Gründe, aus denen ich Perl bevorzugen könnte, sind (ohne darauf beschränkt zu sein):

  • Es wird schneller sein. Hauptsächlich, weil ich für viele der Dinge, die ich tun möchte, keine neuen Prozesse starten muss (Basisname und Verzeichnisname sind die offensichtlichsten Beispiele, aber im Allgemeinen können auch Cut, Grep, Sort und Wc eliminiert werden).
  • Die Handhabung von Strings in Bash ist bestenfalls rudimentär, und die ganze $ IFS-Sache ist super-klobig.
  • Bedingungen in Shell-Skripten können fehlerhaft sein.
  • Das Zitieren in Shell-Skripten kann ein Albtraum sein.
  • Die case-Anweisung der bash lässt über einfache Fälle (NPI) hinaus viel zu wünschen übrig.
  • Arrays in Bash saugen. Hashes in Bash (vorausgesetzt, Ihre Bash ist neu genug, um sie überhaupt zu haben) saugen noch härter.
  • Sobald die Verarbeitung von Dateien oder die Ausgabe von Befehlen über den oben aufgeführten einfachen Fall hinausgeht, beginnt Perl, heftig zu rauchen.
  • CPAN.

Es ist also nicht so, dass Bash in naher Zukunft die Kontrolle über Perl übernehmen wird. Aber nach all den Jahren finde ich immer noch, dass ein einfaches Shell-Skript manchmal einfacher ist als ein einfaches Perl-Skript. Wie gesagt, ich begrüße alle Versuche, mich von etwas anderem zu überzeugen. Aber es ist auch nichts Falsches daran, ein paar verschiedene Werkzeuge in Ihrer Toolbox zu haben.

buzz3791
quelle
Interessanterweise gelten in Ruby nicht alle (?) Der Punkte, da Ruby über at_exit (), realpath (), expand_path (), stat (), heredocs und exceptions ( fail "error" unless system("foobar")) verfügt.
Cezary Baginski
5

Nach meiner Erfahrung ist Bash versus Python ein Kompromiss zwischen Entwicklungszeit und Flexibilität. Eine rudimentäre Lösung für ein Problem kann in der Regel schneller in einem Bash-Skript erstellt werden als in einem Python-Skript.

In Python werden Sie in der Regel mehr über die Struktur Ihrer Lösung nachdenken als über das entsprechende Bash-Skript. Python ist aussagekräftiger als ein Bash-Skript und kann daher im Laufe der Zeit besser skaliert und geändert werden. Es bleibt auch im Allgemeinen besser lesbar.

Bash ist näher am Dateisystem und eignet sich hervorragend für erste Lösungsentwürfe für Probleme, die NICHT genau definiert sind. Aus diesem Grund kann ein Bash-Skript eine gute erste Wahl sein, um einen Prototyp zu erstellen, um ihn vollständig auf Python zu portieren, sobald das Problem besser verstanden wurde.

Travis
quelle
4

Bash ist eine Unix-Shell, die eine Skriptsprache enthält. Es ist eher ein Befehlsprozessor. Sie steuern die Art und Weise, wie Sie Befehle ausführen, Sie führen sie tatsächlich aus.

Perl / Ruby / Python sind Allzwecksprachen.

Wenn Sie ein Shell-Skript möchten, verwenden Sie Bash

Wenn Sie eine komplexere Aufgabe haben oder nicht mit der Shell in Verbindung stehen möchten. Verwenden Sie Python usw.

Ich würde diese Sprachen eigentlich nie vergleichen. Python etc. sind portabel. Sie können sie überall ausführen. Bash ist nur für Unix.

Python usw. hat Tonnen von wiederverwendbaren Bibliotheken, die Millionen von Aufgaben lösen.

Es ist fast das gleiche, wenn Sie fragen. "Wann Sie Paint und wann Photoshop verwenden sollten"

Zum Verarbeiten von E-Mails würde ich wieder Ruby verwenden, da es viele wiederverwendbare Bibliotheken gibt.

Aber der beste Weg wäre, Bash und Ruby zu kombinieren. Das wäre richtig. Wenn Sie ein E-Mail-Verarbeitungsskript in Ruby und Bash erstellen, wird dieses Ruby-Skript aufgerufen und andere Kommandos ausgeführt.

Wenn Sie also einen Befehlsprozessor benötigen, verwenden Sie bash. Sie führen Unix-Befehle aus und steuern sie.

UPDATE nach 7 Jahren (März 2019)

Obwohl sich der Hauptteil meiner Antwort nicht geändert hat, möchte ich darauf hinweisen.

Bash ist auch eine mächtige Skriptsprache. Für die Textverarbeitung könnte es eine absolut legitime Wahl sein.

Bitte lies die Kommentare von mkaito weiter unten. Sie sind alle völlig wahr.

bakytn
quelle
1
Die Skriptuntermenge von Bash ist genauso universell einsetzbar wie jede universelle Skriptsprache. Fügen Sie allgemeine Programme wie sed in die Mischung ein, und Sie haben 90% aller Skriptanforderungen, die Sie jemals haben werden, selbst abgedeckt.
Mkaito
1
bash ist ein Befehlsprozessor, der andere Unix-Befehle und -Programme in ihren Skripten ausführen kann. Wie Sie gesagt haben, sed usw. Er fragt, wann eine bestimmte Sprache ausgewählt werden soll
bakytn
1
Die Shell ist in der Tat ein ausgezeichneter Programmstarter, aber ihre Skriptfunktionen gehen weit darüber hinaus. Ich schlage vor, Sie lernen einige echte Shell-Skripte.
Mkaito
Ich kann auf dem Boden schlafen, aber ich würde es lieber auf einem Bett tun. Die Sprachen können nicht verglichen werden, sie haben unterschiedliche Zwecke.
Bakytn
2
Nun, wenn Bash der Boden ist, muss so etwas wie Haskell ein Nagelbrett sein :-)
mkaito
1

Shell-Skripte wie bash, ksh, zsh, sh und fish sind im Vergleich zu allgemeinen Hochsprachen wie Ruby, Python oder Perl bekanntermaßen überraschend. Während ein Shell-Skript möglicherweise als eine kürzere Datei als das entsprechende Allzweck-Skript beginnt, führen die Überraschungen zu einer Menge defensivem Code, set -euo pipefailum beispielsweise strenge Modi zu aktivieren.

Beispielsweise setzen die meisten Shell-Sprachen die Ausführung von Zeilen in einem Shell-Skript fort, selbst wenn einer der Befehle fehlschlägt. Im Gegensatz dazu versagt eine Allzwecksprache beim ersten Fehler sofort und häufig mit hoher Last, was zu einem sichereren und vorhersehbareren Verhalten in Skripten mit sogar geringer Komplexität führt.

mcandre
quelle
1

Sehr voreingenommener Artikel.

Ich finde bash nicht so schwer zu debuggen. Python ist oft viel zu starr, wohingegen man mit bash sehr kreativ sein kann. Wenn Sie ein guter Querdenker sind, werden Sie bash mögen.

Ich führe Bash-Skripte mit Millionen von DNA-Sequenzierungslesevorgängen in Tausenden von Dateien aus. Und im Gegensatz zu dem, was alle sagen, werden dieselben Versionen der Skripte in C ++ nicht wirklich viel schneller ausgeführt (in wenigen Minuten werden sie voneinander getrennt).

Ich denke, dass Bash, wie Perl, nicht besonders benutzerfreundlich und einfach zu lesen ist. Das macht den Leuten Angst, weil die meisten Leute keine großen abstrakten Denker sind. Aber hellere, kreativere Programmierer lieben es und nutzen es häufig. Wenn Sie sich selbst kennen und wissen, dass Sie ein Gehirn haben, lassen Sie sich nicht abschrecken. Wenn Sie ein Grunddenker sind, halten Sie sich vielleicht an etwas wie Python. Jedem das Seine.

CK
quelle
0

Aus dem "Lama-Buch"

  • Randal L. Schwartz, Tom Phoenix und Brian D Foy, Learning Perl (Sebastopol, CA: O'Reilly, 2011), Kap. 1.2 "Wofür steht Perl?" , §§ "Warum hat Larry [der Schöpfer von Perl] nicht einfach eine andere Sprache verwendet?", P. 5:

Perl versucht, die Lücke zwischen Low-Level-Programmierung (wie in C oder C ++ oder Assembly) und High-Level-Programmierung (wie „Shell“ -Programmierung [zB bash]) zu schließen. Low-Level-Programmierung ist normalerweise schwer zu schreiben und hässlich, aber schnell und unbegrenzt; Es ist schwer, die Geschwindigkeit eines gut geschriebenen Low-Level-Programms auf einer bestimmten Maschine zu übertreffen. Und da kann man nicht viel machen. High-Level-Programmierung im anderen Extremfall ist in der Regel langsam, hart, hässlich und begrenzt. Es gibt viele Dinge, die Sie mit der Shell- oder Stapelprogrammierung überhaupt nicht tun können, wenn auf Ihrem System kein Befehl vorhanden ist, der die erforderliche Funktionalität bietet. Perl ist einfach, fast unbegrenzt, meist schnell und irgendwie hässlich.

Geremia
quelle
0

Verwenden Sie als Faustregel die einfachste Sprache , die für Ihre jeweilige Aufgabe gut genug ist. Und seine Besonderheiten sind nur insoweit wirklich nützlich.

Und was die Lesbarkeit betrifft, ist Bash schrecklich, wenn Ihr Programmierstil schrecklich ist. Wenn Sie einfach den Code dort hineinwerfen, wird er dunkel.

Wenn Sie jedoch den Code in die kürzesten Funktionen aufteilen und die Dinge auf einfach verständliche Weise benennen, ist dies die klarste Sprache, die Sie finden können. Weil es sehr knapp ist.

Als Beispiel ist dies mein neuester Code in Bash. Beachten Sie, wie einfach es zu verstehen und zu tippen ist:

#! /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 "${@}"
Alberto Salvia Novella
quelle