Wie komplex kann ein Programm in Bash geschrieben werden? [geschlossen]

17

Nach einigen sehr schnellen Recherchen scheint Bash eine Turing-vollständige Sprache zu sein .

Ich frage mich, warum wird Bash fast ausschließlich zum Schreiben relativ einfacher Skripte verwendet? Da eine Bash-Shell mit Linux geliefert wird, können Sie Shell-Skripte ohne externen Interpreter oder Compiler ausführen, wie dies für andere gängige Computersprachen erforderlich ist. Dies ist ein großer Vorteil, der in einigen Fällen die Mittelmäßigkeit der Sprache selbst ausgleichen könnte.

Gibt es eine Grenze für die Komplexität solcher Programme? Wird reines Bash verwendet, um komplexe Programme zu schreiben? Ist es möglich, beispielsweise einen Dateikomprimierer / Dekomprimierer in Pure Bash zu schreiben? Ein Compiler? Ein einfaches Videospiel?

Wird es nur deshalb so sparsam verwendet, weil es nur sehr begrenzte Debugging-Tools gibt?

Bregalad
quelle
2
Das shSkript, configuredas im Rahmen des Erstellungsprozesses für sehr viele un * x-Pakete verwendet wird, ist nicht "relativ einfach".
user4556274
@ user4556274 Ist es nicht, wird aber normalerweise auch nicht von Hand geschrieben, sondern aus einem umfangreichen Satz von m4Makros.
Kusalananda
2
Es gibt einen x86-Assembler in Bash, also wird Bash gelegentlich zum Schreiben komplexer Programme verwendet. Warum machen die Leute das nicht öfter? Möglicherweise, weil der Interpreter auch langsam, beschissen und anfällig für "interessante" Fehler ist (siehe zB Shellshock ). Bash-Skripte sind in der Regel exponentiell schwerer zu verwalten, wenn die Größe stimmt. Betrachte den Assembler oben. Kannst du an der Quelle erkennen, ob sie der AT & T- oder der Intel-Syntax entspricht?
Satō Katsura
configureSkripte sind auch langsam, erledigen eine ganze Reihe von nutzlosen Arbeiten und waren Gegenstand einiger amüsanter Ausschreitungen. Natürlich kann die Shell für große Programme verwendet werden, aber andererseits haben die Leute auch Computer aus Conways Game of Life und Minecraft gemacht, und es gibt auch Programmiersprachen wie Brainf ** k und Hexagony . Anscheinend bauen manche Leute gerne etwas aus wirklich kleinen und verwirrenden Atomen. Sie können sogar Spiele mit dieser Idee verkaufen ...
ilkkachu
Ist diese Frage also beantwortbar oder nicht? Sie halten es in der Warteschleife und sagen, es sei unbeantwortbar, aber ich bekomme ein paar gute Antworten. Es wäre schön, kohärent zu sein, da ich neu in dieser SE bin, um mich auf die Art der Fragen zu lenken, die in dieser SE wünschenswert und unerwünscht sind.
Bregalad

Antworten:

30

es scheint, dass Bash eine Turing-vollständige Sprache ist

Das Konzept der Turing-Vollständigkeit ist völlig unabhängig von vielen anderen Konzepten, die in einer Programmiersprache im Großen und Ganzen nützlich sind : Benutzerfreundlichkeit, Ausdruckskraft, Verständlichkeit, Geschwindigkeit usw.

Wenn Turing-Vollständigkeit alle waren wir, würden wir alle Programmiersprachen nicht haben überhaupt , nicht einmal Assemblersprache . Computerprogrammierer würden alle nur in Maschinencode schreiben , da unsere CPUs auch Turing-komplett sind.

Warum wird Bash fast ausschließlich zum Schreiben relativ einfacher Skripte verwendet?

Große, komplexe Shell-Skripte - wie die configurevon GNU Autoconf ausgegebenen Skripte - sind aus vielen Gründen untypisch:

  1. Bis vor relativ kurzer Zeit konnte man nicht überall mit einer POSIX-kompatiblen Shell rechnen .

    Viele Systeme, vor allem ältere, haben technisch eine POSIX-kompatible Shell irgendwo auf dem System, aber es kann nicht wie an einem vorhersagbaren Ort sein /bin/sh. Wenn Sie ein Shell-Skript schreiben und es auf vielen verschiedenen Systemen laufen muss, wie schreiben Sie dann die Shebang-Zeile ? Eine Möglichkeit ist, fortzufahren und zu verwenden /bin/sh, aber Sie können sich auf den Bourne-Shell-Dialekt vor POSIX beschränken, falls er auf einem solchen System ausgeführt wird.

    In Bourne-Shells vor POSIX ist nicht einmal eine Arithmetik integriert. Sie müssen anrufen exproder bcum das zu erledigen.

    Selbst bei einer POSIX-Shell fehlen Ihnen assoziative Arrays und andere Funktionen, die wir in Unix-Skriptsprachen erwartet haben, seit Perl in den frühen 1990er-Jahren zum ersten Mal populär wurde .

    Diese Tatsache aus der Geschichte bedeutet, dass es eine jahrzehntelange Tradition gibt, viele der leistungsstarken Funktionen moderner Shell-Skript-Interpreter der Bourne-Familie zu ignorieren, nur weil Sie nicht darauf zählen können, dass sie überall verfügbar sind.

    Das geht bis heute so: Bash hat bis zur Version 4 keine assoziativen Arrays erhalten , aber Sie werden überrascht sein, wie viele Systeme noch auf Bash 3 basieren. Apple liefert Bash 3 2017 noch mit macOS aus - anscheinend für Lizenzgründe - und Unix / Linux-Server laufen oft sehr lange, aber unberührt in der Produktion, sodass Sie möglicherweise ein stabiles altes System haben, auf dem Bash 3 ausgeführt wird, wie beispielsweise eine CentOS 5-Box. Wenn Sie solche Systeme in Ihrer Umgebung haben, können Sie in Shell-Skripten, die darauf ausgeführt werden müssen, keine assoziativen Arrays verwenden.

    Wenn Sie auf dieses Problem antworten, dass Sie nur Shellskripte für "moderne" Systeme schreiben, müssen Sie damit rechnen, dass der letzte gemeinsame Bezugspunkt für die meisten Unix-Shells der POSIX-Shell-Standard ist , der seither weitgehend unverändert ist Es gibt viele verschiedene Schalen, die auf diesem Standard basieren, aber alle sind in unterschiedlichem Maße von diesem Standard abgewichen. Um wieder assoziative Arrays zu nehmen bash, zshund ksh93alle haben diese Funktion, aber es gibt mehrere Implementierung Inkompatibilitäten. Sie haben dann die Wahl, nur Bash oder nur Zsh oder nur Bash zu verwenden ksh93.

    Wenn Ihre Antwort auf dieses Problem lautet: "Installieren Sie einfach Bash 4" oder ksh93was auch immer, warum installieren Sie dann nicht stattdessen "nur" Perl, Python oder Ruby? Das ist in vielen Fällen inakzeptabel. Standardeinstellungen sind wichtig.

  2. Keine der Shell-Skriptsprachen der Bourne-Familie unterstützt Module .

    In einem Shell-Skript können Sie einem Modulsystem am nächsten kommen, indem Sie den .Befehl eingeben - auch bekannt als sourcebei neueren Bourne-Shell-Varianten -, der auf mehreren Ebenen im Vergleich zu einem geeigneten Modulsystem fehlschlägt. Das grundlegendste davon ist der Namespace .

    Unabhängig von der Programmiersprache beginnt das menschliche Verständnis zu schwinden, wenn eine einzelne Datei in einem größeren Gesamtprogramm mehrere tausend Zeilen überschreitet. Der eigentliche Grund, warum wir große Programme in viele Dateien strukturieren, besteht darin, dass wir ihren Inhalt zu höchstens ein oder zwei Sätzen zusammenfassen können. Datei A ist der Befehlszeilenparser, Datei B ist die Netzwerk-E / A-Pumpe, Datei C ist die Schnittstelle zwischen Bibliothek Z und dem Rest des Programms usw. Wenn Ihre einzige Methode zum Zusammenstellen vieler Dateien in einem einzigen Programm die Texteinbeziehung ist Sie haben eine Grenze gesetzt, wie groß Ihre Programme angemessen wachsen können.

    Zum Vergleich wäre es so, als hätte die Programmiersprache C keinen Linker, nur #includeAnweisungen. Ein solcher C-Lite-Dialekt würde keine Schlüsselwörter wie externoder benötigen static. Diese Funktionen sind vorhanden, um Modularität zu ermöglichen.

  3. POSIX definiert keine Möglichkeit , Variablen auf eine einzelne Shell-Skriptfunktion zu beschränken, geschweige denn auf eine Datei.

    Dadurch werden alle Variablen effektiv global , was wiederum die Modularität und Zusammensetzbarkeit beeinträchtigt.

    Es gibt Lösungen für dieses in Post-POSIX - Schalen - sicherlich in bash, ksh93und zshzumindest - aber das bringt Sie gerade zurück zu Punkt 1 oben.

    Sie können die Auswirkung davon in den Styleguides beim Schreiben von GNU Autoconf-Makros sehen, in denen empfohlen wird , Variablennamen den Namen des Makros als Präfix voranzustellen, was zu sehr langen Variablennamen führt, um die Wahrscheinlichkeit einer Kollision auf ein akzeptables Maß zu reduzieren Null.

    Sogar C ist in dieser Hinsicht um eine Meile besser. Die meisten C-Programme werden nicht nur hauptsächlich mit funktionslokalen Variablen geschrieben, sondern C unterstützt auch das Block-Scoping, sodass mehrere Blöcke innerhalb einer einzigen Funktion Variablennamen ohne Kreuzkontamination wiederverwenden können.

  4. Shell-Programmiersprachen haben keine Standardbibliothek.

    Man kann argumentieren, dass die Standardbibliothek einer Shell-Skriptsprache der Inhalt von ist PATH, aber das besagt nur, dass ein Shell-Skript ein anderes ganzes Programm aufrufen muss, wahrscheinlich eines, das in einer mächtigeren Sprache geschrieben wurde, um Konsequenzen zu erzielen anfangen mit.

    Es gibt auch kein weit verbreitetes Archiv von Shell-Dienstprogrammbibliotheken wie das von Perl verwendete CPAN . Ohne eine große verfügbare Bibliothek mit Utility-Code von Drittanbietern muss ein Programmierer mehr Code von Hand schreiben, damit er weniger produktiv ist.

    Selbst wenn man die Tatsache ignoriert, dass die meisten Shell-Skripte auf externen Programmen basieren, die normalerweise in C geschrieben sind, um nützliche Aufgaben zu erledigen, entstehen all diese pipe()fork()exec()Aufrufketten. Dieses Muster ist unter Unix ziemlich effizient im Vergleich zu IPC und dem Starten von Prozessen unter anderen Betriebssystemen, aber hier ersetzt es effektiv das, was Sie mit einem Unterprogrammaufruf in einer anderen Skriptsprache tun würden , was noch weitaus effizienter ist. Dadurch wird die Höchstgeschwindigkeit für die Ausführung von Shell-Skripten stark begrenzt.

  5. Shell-Skripte sind nur wenig in der Lage, ihre Leistung durch parallele Ausführung zu steigern.

    Bourne - Shells hat &, waitund Pipelines für diese, aber das ist weitgehend nur nützlich für mehrere Programme zu komponieren, nicht für die CPU zu erreichen oder E / A - Parallelität. Sie sind wahrscheinlich nicht in der Lage, die Kerne zu fixieren oder ein RAID-Array nur mit Shell-Scripting zu sättigen, und wenn Sie dies tun, könnten Sie wahrscheinlich eine viel höhere Leistung in anderen Sprachen erzielen.

    Insbesondere Pipelines sind schwache Möglichkeiten, die Leistung durch parallele Ausführung zu steigern. Es können nur zwei Programme gleichzeitig ausgeführt werden, und eines der beiden Programme wird wahrscheinlich zu einem bestimmten Zeitpunkt für die E / A von oder zu dem anderen gesperrt .

    Es gibt heutzutage Wege, wie zum Beispiel xargs -Pund GNUparallel , aber dies widmet sich nur Punkt 4 oben.

    Shell-Skripte können Multi-Prozessor-Systeme praktisch nicht voll ausnutzen und sind daher immer langsamer als gut geschriebene Programme in einer Sprache, die alle Prozessoren des Systems nutzen kann. Um dieses GNU Autoconf- configureSkriptbeispiel noch einmal zu verwenden, führt eine Verdoppelung der Anzahl der Kerne im System kaum zu einer Verbesserung der Geschwindigkeit, mit der es ausgeführt wird.

  6. Shell-Skriptsprachen haben keine Zeiger oder Referenzen .

    Dies verhindert, dass Sie eine Reihe von Aufgaben in anderen Programmiersprachen erledigen können.

    Zum einen bedeutet die Unfähigkeit, indirekt auf eine andere Datenstruktur im Programmspeicher zu verweisen, dass Sie auf die integrierten Datenstrukturen beschränkt sind . Ihre Shell verfügt möglicherweise über assoziative Arrays , aber wie werden sie implementiert? Es gibt verschiedene Möglichkeiten mit unterschiedlichen Kompromissen: Rot-Schwarz-Bäume , AVL-Bäume und Hash-Tabellen sind am häufigsten, aber es gibt auch andere. Wenn Sie einen anderen Satz von Kompromissen benötigen, stecken Sie fest, weil Sie ohne Referenzen nicht die Möglichkeit haben, viele Arten von erweiterten Datenstrukturen von Hand zu rollen. Sie stecken fest mit dem, was Ihnen gegeben wurde.

    Es kann aber auch vorkommen, dass Sie eine Datenstruktur benötigen, in deren Shell-Skript-Interpreter nicht einmal eine geeignete Alternative integriert ist, z. B. ein gerichtetes azyklisches Diagramm , das Sie möglicherweise benötigen, um ein Abhängigkeitsdiagramm zu modellieren . Ich programmiere seit Jahrzehnten und die einzige Möglichkeit, die mir in einem Shell-Skript einfällt, besteht darin, das Dateisystem zu missbrauchen und Symlinks als falsche Referenzen zu verwenden. Das ist die Art von Lösung, die Sie erhalten, wenn Sie sich nur auf die Vollständigkeit von Turing verlassen, die Ihnen nichts darüber aussagt, ob die Lösung elegant, schnell oder einfach zu verstehen ist.

    Fortgeschrittene Datenstrukturen sind nur eine Verwendung für Zeiger und Referenzen. Es gibt unzählige andere Anwendungen für sie , die in einer Shell-Skriptsprache der Bourne-Familie einfach nicht einfach ausgeführt werden können.

Ich könnte weiter und weiter gehen, aber ich denke, Sie verstehen es hier. Einfach ausgedrückt, es gibt viele leistungsfähigere Programmiersprachen für Unix-Systeme.

Dies ist ein großer Vorteil, der in einigen Fällen die Mittelmäßigkeit der Sprache selbst ausgleichen könnte.

Sicher, und genau deshalb verwendet GNU Autoconf für seine configureSkriptausgaben eine absichtlich eingeschränkte Teilmenge der Bourne-Familie von Shell-Skriptsprachen, sodass die configureSkripts praktisch überall ausgeführt werden.

Sie werden wahrscheinlich keine größere Gruppe von Gläubigen finden, die an die Nützlichkeit des Schreibens in einem hoch portierbaren Bourne-Shell-Dialekt glauben als die Entwickler von GNU Autoconf, aber ihre eigene Kreation ist hauptsächlich in Perl geschrieben, plus einige m4und nur ein bisschen Shell Skript; Nur die Ausgabe von Autoconf ist ein reines Bourne-Shell-Skript. Wenn das nicht die Frage aufwirft, wie nützlich das Konzept "Bourne everywhere" ist, weiß ich nicht, wie es sein wird.

Gibt es eine Grenze für die Komplexität solcher Programme?

Technisch gesehen nein, wie Ihre Turing-Vollständigkeitsbeobachtung nahelegt.

Das ist aber nicht dasselbe wie zu sagen, dass beliebig große Shell-Skripte angenehm zu schreiben, einfach zu debuggen oder schnell auszuführen sind.

Ist es möglich, beispielsweise einen Dateikomprimierer / Dekomprimierer in reiner Bash zu schreiben?

"Pure" Bash, ohne irgendwelche Aufrufe zu Dingen in der PATH? Der Kompressor ist wahrscheinlich mit echound hex Escape Sequenzen machbar , aber es wäre ziemlich schmerzhaft zu tun. Der Dekomprimierer kann möglicherweise nicht auf diese Weise geschrieben werden, da er keine Binärdaten in der Shell verarbeiten kann . Am Ende würden Sie u. U. odBinärdaten in das Textformat übersetzen, die native Art der Shell, mit Daten umzugehen.

Sobald Sie anfangen, Shell-Skripte so zu verwenden, wie es beabsichtigt war, um andere Programme zu PATHsteuern, öffnen sich die Türen, da Sie sich nur noch auf das beschränken, was in anderen Programmiersprachen möglich ist habe überhaupt keine Grenzen. Ein Shell-Skript, das seine ganze Kraft PATHentfaltet, indem es andere Programme in der ausführt, läuft nicht so schnell wie monolithische Programme, die in leistungsstärkeren Sprachen geschrieben sind, aber es läuft .

Und genau darum geht es. Wenn Sie ein Programm benötigen, um schnell zu arbeiten, oder wenn es von sich aus leistungsfähig sein muss, anstatt sich die Leistung von anderen zu leihen, schreiben Sie es nicht in Shell.

Ein einfaches Videospiel?

Hier ist Tetris in der Schale . Andere solche Spiele sind verfügbar, wenn Sie auf der Suche sind.

Es gibt nur sehr begrenzte Debugging-Tools

Ich würde die Unterstützung für das Debugging-Tool auf den 20. Platz in der Liste der Funktionen setzen, die zur Unterstützung der Programmierung im Großen erforderlich sind. Eine ganze Reihe von Programmierern verlassen sich viel stärker auf das printf()Debuggen als auf die richtigen Debugger, unabhängig von der Sprache.

In der Shell haben Sie echound set -x, die zusammen ausreichen, um sehr viele Probleme zu debuggen.

Warren Young
quelle
2
Msgstr "Shell - Skripte können nur wenig parallel ausgeführt werden." Meiner Meinung nach unterstützt die Shell die Parallelverarbeitung besser als die meisten anderen Sprachen. Mit einem einzelnen Zeichen können &Sie Prozesse parallel ausführen. Sie können waitdie untergeordneten Prozesse abschließen. Sie können Pipelines und komplexere Netzwerke von Pipes mithilfe von Named Pipes einrichten. Am wichtigsten ist, dass es einfach ist, die Parallelverarbeitung auf die richtige Art und Weise mit sehr wenig Boilerplate-Code durchzuführen und die Risiken und Schwierigkeiten von Multithreading mit gemeinsamem Speicher zu vermeiden.
Sam Watkins
@ SamWatkins: Ich habe Punkt 5 oben aktualisiert, um Ihre Antwort zu adressieren. Auch ich bin ein Fan der Nachrichtenübermittlung zwischen verschiedenen Prozessen, um viele der Probleme zu vermeiden, die der Parallelität von gemeinsamem Speicher inhärent sind, aber hier ging es um die Steigerung der Leistung, nicht um die Kompositionsfähigkeit und so weiter erfordert häufig Parallelität mit gemeinsamem Speicher.
Warren Young
Shell-Skripte eignen sich gut für das Prototyping - aber irgendwann sollte ein Projekt auf eine richtige Programmiersprache und dann im Idealfall auf eine kompilierte Sprache umsteigen. Dann im Extremfall Montage, wie man es beim FFmpeg-Projekt sehen würde. Cmake ist ein gutes Beispiel dafür, was mit Autotools geschehen soll - es ist in C geschrieben und erfordert weder Perl noch Texinfo oder M4. Es ist wirklich peinlich, dass Autotools nach 30 Jahren immer noch so stark auf Shell-Skripte
Steven Penny
9

Wir können überall gehen oder schwimmen. Warum beschäftigen wir uns dann mit Fahrrädern, Autos, Zügen, Booten, Flugzeugen und anderen Fahrzeugen? Sicher, Laufen oder Schwimmen kann anstrengend sein, aber es ist von großem Vorteil, keine zusätzliche Ausrüstung zu benötigen.

Zum einen kann bash, obwohl es sich um Turing-complete handelt, nur ganze Zahlen (nicht zu groß), Zeichenfolgen (eindimensionale) Arrays von Zeichenfolgen und endliche Abbildungen von Zeichenfolgen zu Zeichenfolgen verarbeiten. Für jede andere Art von Daten ist eine lästige Codierung erforderlich, die das Schreiben des Programms erschwert und häufig zu einer Leistung führt, die in der Praxis nicht gut genug ist. Beispielsweise sind Gleitkommaoperationen in bash hart und langsam.

Darüber hinaus hat bash nur sehr wenige Möglichkeiten, mit seiner Umgebung zu interagieren. Es kann Prozesse ausführen, es kann einige einfache Arten von Dateizugriffen ausführen (durch Umleitung), und das war's auch schon. Bash verfügt auch über einen clientseitigen Netzwerkclient. Bash kann leicht genug Null-Bytes ausgeben ( printf \\0), aber keine Null-Bytes in seiner Eingabe analysieren, was es ungeeignet macht, Binärdaten zu lesen. Bash kann nicht direkt andere Dinge tun: Es muss dafür externe Programme aufrufen. Und das ist in Ordnung: Shells sind in erster Linie für die Ausführung externer Programme konzipiert! Shells sind die Klebesprache, um Programme miteinander zu kombinieren. Wenn Sie jedoch ein externes Programm ausführen, bedeutet dies, dass das Programm verfügbar sein muss - und dann verringern Sie den Portabilitätsvorteil:).

Bash hat keine Funktion, die es einfacher macht, robuste Programme zu schreiben, abgesehen von set -e. Es gibt keine (nützlichen) Typen, Namespaces, Module oder verschachtelten Datenstrukturen. Fehler sind die größte Schwierigkeit beim Programmieren. Während die Leichtigkeit, fehlerfreie Programme zu schreiben, nicht immer der entscheidende Faktor bei der Auswahl einer Sprache ist, wird bash in dieser Hinsicht schlecht bewertet. Bash steht auch in Bezug auf die Leistung schlecht da, wenn es darum geht, Programme nicht miteinander zu kombinieren.

Bash lief lange nicht unter Windows, und selbst heute ist es in einer Windows-Standardinstallation nicht vorhanden, und es läuft nicht vollständig nativ (auch nicht in WSL) in dem Sinne, dass es keine Schnittstellen zu hat Windows native Funktionen. Bash läuft nicht unter iOS und wird unter Android nicht standardmäßig installiert. Wenn Sie also keine reine Unix-Anwendung schreiben, ist bash überhaupt nicht portierbar.

Das Erfordernis eines Compilers ist für die Portabilität kein Problem. Der Compiler läuft auf dem Entwicklerrechner. Das Erfordernis eines Interpreters oder von Bibliotheken von Drittanbietern kann ein Problem sein, aber unter Linux ist es ein durch Distributionspakete gelöstes Problem, und unter Windows, Android und iOS werden Komponenten von Drittanbietern im Allgemeinen in ihrem Anwendungspaket gebündelt. Die Art der Portabilitätsbedenken, die Sie haben, sind also keine praktischen Bedenken für Standardanwendungen.

Meine Antwort bezieht sich auf andere Muscheln als Bash. Einige Details variieren von Shell zu Shell, aber die allgemeine Idee ist dieselbe.

Gilles 'SO - hör auf böse zu sein'
quelle
1
Ich glaube, über den Mythos der Portabilität wurde ziemlich häufig gesprochen, nicht sicher, ob ich diesen bestimmten Punkt als Negativ verwenden würde, da er auch für die meisten anderen Sprachen gilt, einschließlich Java. Sogar PHP, das auf einem Windows-Server oder einem * nix-Server ausgeführt wird, weist einige kleine Unterschiede auf, die Sie immer beachten müssen, wenn Sie dumm genug sind, irgendetwas auf einem Windows-Server auszuführen. Viele Dinge laufen nicht auf Android oder iOS, also nicht sicher, wie das ein gültiger Kommentar sein könnte.
Lizardx
7

Einige Gründe, warum ich keine Shell-Skripte für große Programme verwenden sollte:

  • Die meisten Funktionen werden ausgeführt, indem externe Befehle abgebrochen werden, was langsam ist. Im Gegensatz dazu können Programmiersprachen wie Perl das Äquivalent von mkdiroder grepintern leisten .
  • Es gibt keine einfache Möglichkeit, auf C-Bibliotheken zuzugreifen oder direkte Systemaufrufe zu tätigen, was bedeutet, dass z. B. das Videospiel schwer zu erstellen wäre
  • Richtige Programmiersprachen bieten eine bessere Unterstützung für komplexe Datenstrukturen. Bash hat zwar Arrays und assoziative Arrays, aber ich möchte nicht an eine verknüpfte Liste oder einen Baum denken.
  • Die Shell verarbeitet Befehle, die aus Text bestehen. Binärdaten (dh Variablen, die NUL-Bytes enthalten (Bytes mit dem Wert Null)) sind schwer bis unmöglich zu handhaben. Kommt etwas auf die Shell an, zshhat etwas Unterstützung. Dies liegt auch daran, dass die Schnittstelle für externe Programme zumeist textbasiert \0ist und als Trennzeichen verwendet wird.
  • Auch aufgrund von externen Befehlen ist die Trennung zwischen Code und Daten etwas schwierig. Erleben Sie alle Probleme, die beim Zitieren von Daten in einer anderen Shell auftreten (z. B. beim Ausführen von bash -c ...oder ssh -c ...).
ilkkachu
quelle
Dies ist für mich das genaueste Negativ, da ich als jemand, der viele große Bash-Skripte ausführt, ungefähr das wäre, was ich auch als Negativ verzeichnen würde. Ich habe jedoch festgestellt, dass Bash beim Vergleich ähnlicher Funktionen nicht viel langsamer ist als andere kompilierte Sprachen. Ich habe den schleichenden Verdacht, dass es sich aufgrund des Geschwindigkeitsunterschieds nicht lohnen würde, wenn ich versuchen würde, einige der komplizierteren Dinge zu schreiben, die ich in Python-Bash habe. Allerdings fand ich Bash alleine zu limitiert, aber Bash + Gawk funktioniert gut, Gawk ist fast echt.
Lizardx