Was sind die praktischen Unterschiede zwischen Bash und Zsh?

Mit der Nachricht, dass Catalina standardmäßig Zsh anstelle von Bash verwenden wird , finde ich viele Ergebnisse, die mich über den Wechsel informieren und dass er Probleme mit Shell-Skripten verursachen kann, aber ich bin mit Zsh nicht vertraut genug, um zu wissen, was diese Probleme sind mag sein.

Meine Shell-Skripte sind wirklich nicht so kompliziert, aber ich habe Bash bisher nur unter macOS und Linux verwendet - null Erfahrung mit Zsh. Kann jemand einen einfachen praktischen Vergleich oder spezifische Stolpersteine ​​liefern, die ich kennen muss, damit ich anfangen kann, darauf hinzuarbeiten, für die neue Shell bereit zu sein, wenn Catalina veröffentlicht wird?

All dieser Trubel, den Sie gelesen haben, bedeutet viel um nichts zu tun. Das Betriebssystem weist beim Erstellen neuer Benutzer eine "Standard" -Shell zu, kein Grund mehr. Bash wird nicht verschwinden, und Sie können es als Ihre Shell oder eine der anderen derzeit angebotenen Shells verwenden.
Als jemand, der beide verwendet hat und auf bash gelandet ist – das einzige, was mich wirklich, zutiefst unglücklich mit zsh gemacht hat, war seine Entscheidung, die POSIX-Compliance zu brechen, wenn der Standard zugegebenermaßen schlechte Designentscheidungen auf eine Weise kanonisiert, die es leicht machte, schlampig zu werden Korrektheit beim Versuch, Skripte zu schreiben, die mit anderen Shells mit strikter POSIX-Obermenge kompatibel sein mussten. Leider kann dieses "einzige Ding" ziemlich groß sein. Trotzdem wird ksh93 nicht verschwinden, und jeder, der sich ernsthaft mit Bash beschäftigt, würde sowieso nicht die alten 3.x-Release-Apple-Schiffe verwenden.
Als Follow-up - installierte Catalina gestern, wechselte zu zsh, importierte bash_history und kopierte einige meiner bevorzugten Aliase von bash_profile, nichts scheint kaputt gegangen zu sein. Schätzen Sie alle Informationen, die von allen hier bereitgestellt werden, und hoffentlich hilft es auch anderen.
@CharlesDuffy: Guter Kommentar. WRT ist "ernst" und verwendet bash version 3.2.57(1): Wissen Sie, ob Apple bashetwas "wichtiges" auf dem System verwendet?

Antworten (4)

Zunächst einige wichtige Dinge:

  1. Bash verschwindet nicht . Wenn Sie bereits bash verwenden, ändert sich für Sie nichts. Alles, was sich ändert, ist, dass zsh die Standard-Anmelde-Shell für neue Konten ist , und selbst dann können Sie stattdessen bash auswählen.
  2. Skripte sind nicht betroffen . Was sich ändert, ist die Shell für die interaktive Verwendung, dh die Shell in Terminals (und auch ein paar andere Dinge, die die Login-Shell verwenden, wie zum Beispiel crontabs). Wenn Sie ein Skript in einer Datei mit Ausführungsberechtigungen haben, das mit einer Shebang-Zeile wie #!/bin/bashoder #!/bin/shoder beginnt #!/usr/bin/env bash, funktioniert es genau wie zuvor.
  3. Die Syntax von Zsh ist nicht vollständig mit Bash kompatibel, aber nah dran. Viele Codes werden weiter funktionieren, zum Beispiel typische Aliase und Funktionen. Die Hauptunterschiede liegen in den interaktiven Konfigurationsfunktionen.

Angenommen, Sie erwägen, zu zsh zu wechseln, was seit Jahren möglich ist, hier sind die Hauptunterschiede, auf die Sie stoßen werden. Dies ist keine vollständige Liste!

Hauptunterschiede für die interaktive Nutzung

Konfigurationsdateien : bash liest (hauptsächlich) .bashrcin interaktiven Shells ohne Anmeldung (aber macOS startet standardmäßig eine Anmelde-Shell in Terminals) .profileoder .bash_profilein Anmelde-Shells und .inputrc. Zsh liest (hauptsächlich) .zshrc(in allen interaktiven Shells) und .zprofile(in Login-Shells). Das bedeutet, dass keine Ihrer Bash-Anpassungen angewendet wird: Sie müssen sie portieren. Sie können die Dateien nicht einfach kopieren, da viele Dinge angepasst werden müssen.

Tastenbelegungen verwenden eine völlig andere Syntax. Bash verwendet .inputrcund das bindeingebaute , um Schlüssel an readline - Befehle zu binden . Zsh verwendet das bindkeyeingebaute , um Schlüssel an zle - Widgets zu binden . Die meisten readline-Befehle haben ein zsh-Äquivalent, aber es ist nicht immer eine perfekte Entsprechung.

Apropos Tastenbelegung: Wenn Sie Vi(m) als In-Terminal-Editor, aber nicht als Befehlszeilenmodus in der Shell verwenden, werden Sie feststellen, dass zsh standardmäßig den vi-Bearbeitungsmodus (dh mit Befehls- und Einfügemodus) verwendet, wenn EDITORoder VISUAList auf vioder setzen vim. bindkey -ewechselt in den emacs-Modus (dh wo Sie immer direkt tippen können).

Eingabeaufforderung : bash legt die Eingabeaufforderung (hauptsächlich) fest, von der Backslash-EscapesPS1 enthalten sind . Zsh legt die Eingabeaufforderung hauptsächlich fest, von der Prozente entkommen . Obwohl die Konzepte ähnlich sind, sind die Escape-Codes völlig unterschiedlich. Die Funktionalität von bash ist in zsh über die Hook-Funktionen und verfügbar . Zsh hat mehr Bequemlichkeitsmechanismen, um ausgefallene Eingabeaufforderungen zu erstellen, einschließlich eines Mechanismus für Eingabeaufforderungsthemen .PS1PROMPT_COMMANDprecmdpreexec

Die grundlegenden Befehlszeilenverlaufsmechanismen (Navigation mit Up/ Down, Suche mit Ctrl+ R, Verlaufserweiterung mit !!und Freunden, Abrufen des letzten Arguments mit Alt+ .oder $_) funktionieren auf die gleiche Weise, aber es gibt viele Unterschiede in den Details, zu viele, um sie hier aufzulisten . Sie können Ihre .bash_historynach kopieren .zsh_history, wenn Sie keine Shell-Option geändert haben, die das Dateiformat ändert.

Vervollständigung : Beide Shells verwenden standardmäßig einen grundlegenden Vervollständigungsmodus, der Befehls- und Dateinamen größtenteils vervollständigt, und wechseln in einen ausgefallenen Modus, indem sie bash_completionin bash eingebunden oder compinitin zsh ausgeführt werden. Sie werden einige Befehle finden, die bash besser handhabt, und einige, die zsh besser handhabt. Zsh ist normalerweise präziser, gibt aber manchmal auf, wenn bash etwas macht, das nicht korrekt, aber sinnvoll ist. Um mögliche Vervollständigungen für einen Befehl anzugeben, verfügt zsh über drei Mechanismen:

Viele der shoptEinstellungen von Bash haben eine Entsprechung setoptin zsh.

Zsh behandelt standardmäßig keinen #Kommentarstart auf der Befehlszeile, sondern nur in Skripten (einschließlich .zshrcund dergleichen). Um interaktive Kommentare zu aktivieren, führen Sie setopt interactive_comments.

Hauptunterschiede beim Scripting

(und natürlich für Power-User auf der Kommandozeile)

Nimmt in bash $fooden Wert von foo, teilt ihn bei Leerzeichen und ersetzt für jeden durch Leerzeichen getrennten Teil, wenn er Platzhalterzeichen enthält und mit einer vorhandenen Datei übereinstimmt, das Muster durch die Liste der Übereinstimmungen. Um nur den Wert von zu erhalten foo, benötigen Sie "$foo". Gleiches gilt für die Befehlsersetzung $(foo). In zsh $fooist der Wert von foound $(foo)die Ausgabe von foominus der letzten Zeilenumbrüche, mit zwei Ausnahmen. Wenn ein Wort leer wird, weil leere, nicht in Anführungszeichen gesetzte Variablen erweitert werden, wird es entfernt (z. B. a=; b=; printf "%s\n" one "$a$b" three $a$b fivegibt one, eine leere Zeile, three, five) aus. Das Ergebnis einer Befehlsersetzung ohne Anführungszeichen wird an Leerzeichen geteilt, aber die Teile werden keinem Wildcard-Abgleich unterzogen.

Bash- Arrays werden von 0 bis (Länge-1) indiziert. Zsh-Arrays werden von 1 bis Länge indiziert. Sie können die 0-Indizierung mit zum Standard machen setopt ksh_arrays. Zsh erfordert weniger geschweifte Klammern (es sei denn, ksh_arrayses ist aktiviert). Angenommen zum Beispiel a=(first second third "" last).

Funktionalität Bash-Syntax Idiomatische zsh-Syntax Erweiterung
Erstes Element ${a[0]} $a[1] first
Zweites Element ${a[1]} $a[2] second
Letztes Element ${a[${#a[@]}-1]} $a[-1] last
Länge ${#a[@]} $#a 5
Alle Elemente "${a[@]}" "${a[@]}"oder"${(@)a}" first second third(leeres Wort)last
Alle nicht leeren Elemente $a first second third last

Bash hat zusätzliche Wildcard-Muster wie zum Beispiel @(foo|bar)to match foooder bar, die nur mit aktiviert werden shopt -s extglob. In zsh können Sie diese Muster mit aktivieren , aber es gibt auch setopt ksh_globeine einfacher zu schreibende native Syntax wie z . Zsh ist für das rekursive Verzeichnistraversal vorgesehen (ebenso wie die moderne Bash, aber nicht die Bash 3.2, die mit macOS geliefert wird).(foo|bar)setopt extended_glob.zshrc**/

Wenn ein Platzhaltermuster in Bash standardmäßig mit keiner Datei übereinstimmt, bleibt es unverändert. In zsh erhalten Sie standardmäßig einen Fehler, was normalerweise die sicherste Einstellung ist. Wenn Sie einen Platzhalterparameter an einen Befehl übergeben möchten, verwenden Sie Anführungszeichen. Mit können Sie zum Bash-Verhalten wechseln setopt no_nomatch. Sie können nicht übereinstimmende Wildcard-Muster stattdessen mit zu einer leeren Liste erweitern setopt null_glob.

In Bash läuft die rechte Seite einer Pipeline in einer Subshell. In zsh läuft es in der übergeordneten Shell, sodass Sie Dinge schreiben können wie somecommand | read output.

Einige nette zsh-Features

Hier sind ein paar nette zsh-Features, die bash nicht hat (zumindest nicht ohne ernsthaftes Ellbogenfett). Noch einmal, dies ist nur eine Auswahl derjenigen, die ich für die nützlichsten halte.

Glob-Qualifizierer ermöglichen das Abgleichen von Dateien basierend auf Metadaten wie Zeitstempel, Größe usw. Sie ermöglichen auch das Optimieren der Ausgabe. Die Syntax ist ziemlich kryptisch, aber äußerst praktisch. Hier sind ein paar Beispiele:

  • foo*(.): Nur Übereinstimmung mit regulären Dateien foo*und symbolische Links zu regulären Dateien, nicht zu Verzeichnissen und anderen speziellen Dateien.
  • foo*(*.): nur ausführbare reguläre Dateien, die mit foo*.
  • foo*(-.): Nur reguläre Dateien, die übereinstimmen foo*, keine symbolischen Links und andere spezielle Dateien.
  • foo*(-@): Nur baumelnde symbolische Links passen foo*.
  • foo*(om): die passenden Dateien foo*, sortiert nach Datum der letzten Änderung, neueste zuerst. Beachten Sie, dass es seine eigene Sortierung durchführt, wenn Sie dies an übergeben ls. Dies ist besonders nützlich bei …
  • foo*(om[1,10]): die 10 neuesten Dateien, die mit übereinstimmen foo*, die neuesten zuerst.
  • foo*(Lm+1): übereinstimmende Dateien foo*, deren Größe mindestens 1 MB beträgt.
  • foo*(N): wie foo*, aber wenn dies zu keiner Datei passt, wird eine leere Liste erzeugt, unabhängig von der Einstellung der null_globOption (siehe oben).
  • *(D): Übereinstimmung mit allen Dateien, einschließlich Punktdateien (außer .und ..).
  • foo/bar/*(:t)(unter Verwendung eines Verlaufsmodifikators ): die Dateien in foo/bar, aber nur mit dem Basisnamen der Datei. Wenn es zB ein gibt foo/bar/qux.txt, wird es als erweitert qux.txt.
  • foo/bar/*(.:r): Nehmen Sie normale Dateien unter foo/barund entfernen Sie die Erweiterung. ZB foo/bar/qux.txtwird erweitert als foo/bar/qux.
  • foo*.odt(e\''REPLY=$REPLY:r.pdf'\'): Nimm die Liste der passenden Dateien foo*.odtund ersetze sie .odtdurch .pdf(unabhängig davon, ob die PDF-Datei existiert).

Hier sind ein paar nützliche zsh-spezifische Wildcard-Muster .

  • foo*.txt~foobar*: alle .txtDateien, deren Name mit beginnt, fooaber nicht foobar.
  • image<->.jpg(n): alle .jpgDateien, deren Basisname imageeine Zahl folgt, zB image3.jpgund image22.jpgaber nicht image-backup.jpg. Der Glob-Qualifizierer (n)bewirkt, dass die Dateien in numerischer Reihenfolge aufgelistet werden, dh image9.jpgkommt vor (Sie können dies auch ohne mit image10.jpgfestlegen ).-nsetopt numeric_glob_sort

Um Dateien massenweise umzubenennen , bietet zsh ein sehr praktisches Werkzeug: die zmvFunktion . Empfohlen für Ihre .zshrc:

autoload zmv
alias zcp='zmv -C' zln='zmv -L'

Beispiel:

zmv '(*).jpeg' '$1.jpg'
zmv '(*)-backup.(*)' 'backups/$1.$2'

Bash hat einige Möglichkeiten, Transformationen anzuwenden, wenn der Wert einer Variablen übernommen wird . Zsh hat einige davon und noch viel mehr .

Zsh hat eine Reihe kleiner praktischer Funktionen, um Verzeichnisse zu wechseln . Schalten Sie ein setopt auto_cd, um in ein Verzeichnis zu wechseln, wenn Sie seinen Namen eingeben, ohne tippen zu müssen cd(bash hat dies heutzutage auch). Sie können die Form mit zwei Argumentencd verwenden , um in ein Verzeichnis zu wechseln, dessen Name dem aktuellen Verzeichnis nahe kommt. Wenn Sie beispielsweise in sind /some/where/foo-old/deeply/nested/insideund zu gehen möchten /some/where/foo-new/deeply/nested/inside, geben Sie einfach ein cd old new.

Um einer Variablen einen Wert zuzuweisen, schreibt man natürlich VARIABLE=VALUE. Um den Wert einer Variablen interaktiv zu bearbeiten, führen Sie einfach vared VARIABLE.

Abschließender Rat

Zsh verfügt über eine Konfigurationsschnittstelle, die einige der gängigsten Einstellungen unterstützt, einschließlich vorgefertigter Rezepte für Dinge wie die Vervollständigung ohne Berücksichtigung der Groß- und Kleinschreibung. So führen Sie diese Schnittstelle (erneut) aus (die erste Zeile wird nicht benötigt, wenn Sie eine Konfigurationsdatei verwenden, die von bearbeitet wurde zsh-newuser-install):

autoload -U zsh-newuser-install
zsh-newuser-install

Aus Gründen der Abwärtskompatibilität mit Versionen aus den 1990er Jahren sind viele der nützlichen Funktionen von zsh standardmäßig deaktiviert, da überhaupt keine Konfigurationsdatei vorhanden ist. zsh-newuser-installschlägt einige empfohlene Funktionen zum Aktivieren vor.

Es gibt viele zsh-Konfigurationsframeworks im Web (viele davon sind auf Github ). Sie können eine bequeme Möglichkeit sein, mit einigen leistungsstarken Funktionen zu beginnen. Die Kehrseite der Medaille ist, dass sie Sie oft daran hindern, die Dinge so zu tun, wie der Autor es tut, also hindern sie Sie manchmal daran, die Dinge so zu tun, wie Sie es möchten. Verwenden Sie sie auf eigene Gefahr.

Das zsh-Handbuch enthält viele Informationen, ist jedoch häufig knapp und schwer verständlich geschrieben und enthält nur wenige Beispiele. Zögern Sie nicht, online nach Erklärungen und Beispielen zu suchen: Wenn Sie nur den leicht verständlichen Teil von zsh im Handbuch verwenden, werden Sie etwas verpassen. Zwei gute Ressourcen sind die Mailingliste zsh-users und Unix Stack Exchange . Eine umfangreiche Sammlung von Artikeln zum Wechseln zu zsh auf dem Mac finden Sie auf scriptingosx.com und ein nützliches Ruby-Skript, um Ihre Befehlshistorie mitzunehmen , finden Sie auf Github.

Jetzt frage ich mich, ob das erstaunliche ctrl-o auf zsh funktioniert. Natürlich funktioniert es auch nicht unter Mac OS auf Bash, daher ist es für diese Antwort oder Site nicht wirklich relevant. Ich konnte bei einer schnellen Online-Suche keine Informationen zu ctrl-o in zsh finden, aber andererseits sind die Informationen zu ctrl-o in bash auch allgemein ungenau ...
@Jasper Ich wusste nicht, dass Bash das hat. Der Beschreibung nach macht Co in zsh dasselbe mit den Standardtastenbelegungen.
Ich war froh zu sehen, dass Sie den Abschnitt „Einige nette zsh-Funktionen“ aufgenommen haben, und habe ihn gespannt gelesen, um zu verstehen, warum Apple möglicherweise die Entscheidung getroffen hat, von der extrem verbreiteten Bash auf die viel weniger beliebte Zsh umzusteigen. Ich habe dort überhaupt nichts gefunden, was auch nur annähernd überzeugend wäre, um den Wechsel zu rechtfertigen. Die Liste ist offensichtlich nicht erschöpfend, aber haben Sie die Schlagzeilenmerkmale von Zsh weggelassen, weil sie offensichtlich sein sollten? Was fehlt mir hier?
@CodyGray Ich weiß es nicht und Apple ist es nicht gewohnt, sich zu rechtfertigen. Es könnte etwas damit zu tun haben, dass es im umgekehrten Fall keine „nice bash features“-Sektion gäbe. Oder es kann daran liegen, dass die letzte Nicht-GPLv3-Bash sehr alt wird, während zsh eine liberalere Lizenz hat.
Mein Verständnis war, dass die Lizenzierung im Wesentlichen der einzige Grund war. Das ist auch der Grund, warum bash auf macOS immer noch v3 ist. Auf der Straße heißt es, dass bash nicht aktualisiert wird und die Erwartung ist, dass es entfernt wird, es sei denn, der Endbenutzer installiert es über brew oder etc. Mein Plan war, eher früher als später für macOS zu zsh zu wechseln, aber ich bleibe dabei bash für den Moment auf Debian.
Was ist mit nicht interaktiven Skripten, die Terminal nicht verwenden (wie Automator oder Systemjobs)? (Hmm, ich nehme an, sie verwenden einfach go by the #!und sind von der Standard-Login-Shell unbeeinflusst)
@wisbucky-Skripte sind nicht betroffen. Warum sind Automator- oder Systemjobs eine Ausnahme?
Unvoreingenommene und informative Antwort - es wurde viel Zeit und Mühe investiert. Außerdem ein toller Denkanstoß ! Nachdem ich es gelesen habe, bin ich von dem Gedanken beeindruckt, dass ich bei bleiben werde bash, aber eine aktuelle Version via bekomme, MacPortsdie neben der von Apple bereitgestellten Version 3.2 läuft bash. Meiner Meinung nach hat sie zshviele großartige Funktionen, die ich wahrscheinlich nie verwenden werde ... wie die teure Kamera, die ich kürzlich gekauft habe!
Was ist die Bedeutung von one[1]? Es ist kein oneArray definiert.
@Isaac Es ist das erste Element des Arrays a. Erweitert in bash $aimmer zum ersten Element des Arrays, selbst wenn darauf etwas folgt, das wie ein Array-Index aussieht.
Sie wollen also sagen, dass in bash a=(one two); echo $a[1] gedruckt wird one[1](das haben Sie dort oben in der Antwort geschrieben), stattdessen wird in zsh nur gedruckt one. Ich musste wirklich viel neu lesen, um diese Bedeutung zu verstehen. Das Wechseln der Shell alle paar Wörter macht die Aussage meiner Meinung nach schwer lesbar. Könnte man es einfacher und weniger kompliziert ausdrücken?
@Jasper Verwenden Sie "stty discard undef", damit ctrl-o auf dem Mac funktioniert.

Wechseln Sie jetzt Ihre Schale und testen Sie – ohne Wartezeit.

chsh -s /bin/zsh

Außerdem würde ich schätzen, dass 95 % der macOS-Benutzer keine Befehlszeile verwenden, und von denen, die dies tun, müssen weitere 95 % nichts Wesentliches oder überhaupt nichts ändern. (Ich wette, es ist eher so, dass 10% der 1%, die wissen, dass Shells existieren, etwas anderes tun müssen, als ein paar Zeilen in ihren .dot-Dateien zu portieren.)

Ihre Eingabeaufforderung wird sich ändern, und wenn Sie Ihre Eingabeaufforderung auf geändert haben bash, ist der Weg, sie zu ändern, zshnicht schwieriger und nicht weniger dokumentiert als bash.

Die neueren Granaten würden niemals vom Boden abheben, wenn sie wichtige Gegenstände zerschmetterten oder eine schmerzhafte Anpassungsphase verursachten. Wenn Sie eine grundlegendere Veränderung wünschen und wirklich eine Muschel wollen, müssen Sie darüber nachdenken und es erfordert Training und die Absicht, sie anzunehmen – versuchen Sie es mit Fisch .

Ich bin im Konflikt mit fish. Ich benutze es jetzt seit zwei Jahren, aber die Inkompatibilität einiger kopierter/eingefügter Zeilen ist ermüdend. Andererseits ist es eine sehr praktische Shell (die automatischen Vorschläge ohne <kbd>Tab</kbd> sind ausgezeichnet)
Ich wollte Fisch lieben, ich möchte Fisch immer noch lieben, aber ich habe zu viele Muschelkonstrukte aus einem Jahrzehnt, um kshdiese Falte jemals wirklich zu verlassen. Ich werde bash gerne hinter mir lassen und mich jetzt ganz persönlich mit zsh befassen.
Ich bin absolut überwältigt von Fisch. Es ist wirklich nur eine weitere Unix-ähnliche Shell mit etwas weniger Cruft. (Immerhin steht auf der Homepage wörtlich „Endlich eine Kommandozeilen-Shell für die 90er“.) Die einzige neue Shell, die ich in den letzten Jahren gesehen habe und die wirklich etwas Neues auf den (Mainstream-)Tisch gebracht hat, war PowerShell, das leider viel zu lange auf Windows beschränkt war und immer noch auf .NET beschränkt ist. Es gibt immer noch nicht so viel Neues in PowerShell, was nicht schon zB in DCL oder JCL gemacht wurde, aber es wurde auf (etwas) geschmackvolle Weise gemacht.
@bmike Warum dann nicht einfach ksh verwenden? Apple liefert die aktuellste Version aus. Ich selbst habe vor langer Zeit bash punted und sehe keinen Grund, jetzt mit zsh zu beginnen.
Diese Antwort beschreibt jedoch überhaupt nicht die Unterschiede zwischen bash und zsh ... und ich bin mir nicht ganz sicher, warum die Angabe, dass "95% der macOS-Benutzer keine Befehlszeile verwenden" für eine Frage eines Benutzers relevant ist offensichtlich verwendet bash.
fishist nichts. Sie möchten wirklich ein einzigartiges Shell-Erlebnis, verwenden Sie tclsh.
Bevor man leichtsinnig wechselt, sollte man Vorlieben und Historie verschieben. Ohne eine solche Warnung oder Anleitung ist Ihre Empfehlung unvollständig und kann zu unerwarteten Schwierigkeiten führen.
Anweisungen zum Verschieben von Konfiguration und Verlauf finden Sie hier scriptingosx.com/2019/06/…
@mico Das ist so eine tolle Ressource. Das wäre eine großartige Bearbeitung des Beitrags.
danke @bmike. Ich fasste Mut und bearbeitete die großartige Hauptantwort
@Mavrik Werfen Sie einen Blick auf Armin Briegels erstaunlich erstaunlichen Blog und noch besseres Buch über die Unterschiede. Da die richtige Behandlung des Themas (IMO) Zehntausende von Wörtern erfordert, habe ich mich entschieden, mich auf die Leichtigkeit zu konzentrieren, das Wasser zu ändern und zu testen. Schließlich hängt die wirkliche Antwort stark von jedem Einzelnen ab und davon, was er speziell zum Bash beigetragen hat.
Gute Antwort; es ist praktisch und entgegenkommend - das ist es wirklich. :) Aber für mich gibt es 2 Dinge: 1) Apples Marktkapitalisierung liegt bei über 1 Billion USD . 2) Ich fühle mich „abgezockt“ , wenn ein 1-Tilliarden-Dollar-Unternehmen 15 Jahre alte Software mit einem neuen 4.000-Dollar-Computer ausliefert, den es verkauft. Ich liebe meinen Mac, ich gehe nicht zurück, aber... diese #AntiqueSoftware ist keine gute Sache.
@Seamus Sie könnten schockiert sein, wie klein das Team ist, das daran arbeitet. Apple hat versucht, größere Teams zu bilden, und es hat uns schlechtere Ergebnisse gebracht. Schauen Sie nicht auf die prozentualen Einnahmen, die Mac einbringt, ich vermute, wir haben mehr Mac-Ingenieure, als die Zahlen basierend auf der Geschichte zulassen würden.
@Seamus Sie haben diese Billion mit dem Verkauf von Telefonen und Kürzungen verdient, nicht mit dem Verkauf von Macs. Die besten Leute, die Apple hat, arbeiten an iOS. Wir sind Eisbären in einer sich erwärmenden Arktis und der Mac ist unser Eis. Sehr bald werden wir schwimmen, und bald darauf werden wir ohne Fanfare unter die Wellen gleiten, weil Leute, die über iOS in das Ökosystem eingetreten sind, nicht wissen, wie gut der Mac früher war, und daher nicht trauern werden seine Relevanz als Plattform.
@chiggsy: Vielleicht hast du Recht. Ich schätze, die Zeit wird es zeigen. In der Zwischenzeit habe ich MacPorts installiert und finde es ausgezeichnet und arbeite an einem macOS/Linux-Dual-Boot - fast geschafft :) Die Hardware ist es wert, eingespart zu werden; die Software - äh...

Meine Shell-Skripte sind wirklich nicht so kompliziert

Haben Ihre Shell-Skripte Shebang-Zeilen (beginnen mit #! /bin/bashoder ähnlich)? Wenn nicht, haben Sie möglicherweise unbeabsichtigt eine Bash-Funktion verwendet, bei der Skripts ohne einen Shebang mit Bash ausgeführt werden. Andere Shells wie dash oder zsh überlassen dies dem Betriebssystem, das normalerweise /bin/shstattdessen verwendet wird. /bin/shunter macOS ist und wird wahrscheinlich eine Kopie von bleiben /bin/bash, aber die Ausführung von bash mit dem Namen shführt zu einem anderen Verhalten. Die Einzelheiten sind das Bash-Handbuch, 6.11 Bash POSIX mode . Ein paar Punkte:

  1. Bash sorgt dafür, dass die POSIXLY_CORRECTVariable gesetzt wird.

Diese Umgebungsvariable kann das Verhalten einer Reihe anderer Tools beeinflussen, insbesondere wenn Sie GNU-Tools installiert haben.

  1. Prozesssubstitution ist nicht verfügbar.

Prozesssubstitution ist die <(...)or- >(...)Syntax.

  1. Die eingebauten Funktionen .und sourcedurchsuchen das aktuelle Verzeichnis nicht nach dem Dateinamen-Argument, wenn es bei der Suche nach PATH nicht gefunden wird.

Wenn Ihr Skript also . fooerwartet hat, dass es eine Datei mit dem Namen im aktuellen Verzeichnis bezieht foo, funktioniert das nicht. Sie sollten . ./foostattdessen tun.

Wie Sie anhand der Zahlen erraten können, gibt es viele kleine Unterschiede im Verhalten von bash im POSIX-Modus. Verwenden Sie am besten einen Shebang, wenn Sie Bash für Ihre Skripte verwenden möchten.

Bei der Überprüfung sieht es so aus, als ob die überwiegende Mehrheit der Shell-Skripte, die ich geschrieben habe, entweder explizit /bin/bash im Shebang (sehr wenige von ihnen) oder /bin/sh (fast alle) verwenden, so dass dies zumindest der Fall sein sollte kein Thema sein. Danke.
Ich denke, Prozesssubstitution ist jetzt verfügbar. Ich habe es auch erfolgreich auf Catalina ausprobiert. Siehe: zsh.sourceforge.net/Intro/intro_7.html
@Siu hilft immer noch nicht Skripten, die /bin/shoder /bin/bashim Shebang verwenden. Zsh ist nur die standardmäßige interaktive Shell, sie hat Bash nicht überall ersetzt
@muru Ah, ich verstehe. Ich habe die Antwort nicht sorgfältig gelesen und dachte, dass der Autor über die Prozesssubstitution sprach, die in zsh😅 nicht verfügbar ist

Im Geiste, die Dinge einfach zu halten ...

Kann jemand einen einfachen praktischen Vergleich oder spezifische Stolpersteine ​​liefern, die ich kennen muss, damit ich anfangen kann, darauf hinzuarbeiten, für die neue Shell bereit zu sein, wenn Catalina veröffentlicht wird?

Wenn Sie daran denken, die neue Standard-Shell zu verwenden, sollten Sie Folgendes in Betracht ziehen:

  • Wenn Sie Zsh ausprobieren und einige der Unterschiede spüren möchten, ohne die Shell-Einstellungen auf Ihrem Computer zu ändern, können Sie Powerline10k in einem Docker-Container ausprobieren und sehen, ob es Ihr Ding ist.
  • Wenn Sie nicht den ganzen Schnickschnack brauchen und Bash nur für grundlegende Skripte verwenden, ist es ziemlich einfach, Ihre Shell so einzurichten, wie andere hier erklärt haben. Und wenn Sie sich entscheiden, Funktionen in Bash 5 zu verwenden , ist dies ein ziemlich triviales Upgrade für macOS .
  • Wenn Sie die Portabilität Ihrer Skripte verbessern möchten, damit sie mit größerer Wahrscheinlichkeit in beiden Shells wie erwartet funktionieren, testen Sie sie auf POSIX-Konformität und entfernen Sie alle "Bashismen". Ich habe ShellCheck dafür verwendet und es funktioniert recht gut für weniger komplizierte Skripte.

Auch wenn kein bestimmter Weg klar ist, sollten Ihnen diese drei Ansätze genug Vertrauen geben, um eine fundierte Entscheidung zu treffen, ohne den Problem- oder Lösungsraum zu überarbeiten.