Wird empfohlen, zsh anstelle von Bash-Skripten zu verwenden? [geschlossen]

25

Kann ich davon ausgehen, dass genug Leute zshinstalliert haben, um Skripte mit einem auszuführen?

#!/usr/bin/env zsh

als shebang?

Oder können meine Skripte dadurch auf zu vielen Systemen nicht mehr ausgeführt werden?

Klarstellung: Ich interessiere mich für Programme / Skripte, die ein Endbenutzer ausführen möchte (wie unter Ubuntu, Debian, SUSE, Arch usw.).

Profpatsch
quelle
4
Komische Frage. Wer ist dein Ziel? In bestimmten Kreisen (Ruby-on-Rails-Webentwickler) ist dies zshmöglicherweise populär, während es in anderen Kreisen ( Bankensektor) so gut wie unbekannt ist. Ich denke, Sie sollten viel mehr Informationen geben, wenn Sie diesbezüglich geeignete Ratschläge benötigen.
Rahmu
Allgemeine Linux-Endbenutzerwelt.
Profpatsch
2
WRT "Allgemeine Linux-Endbenutzerwelt", zsh ist kein Standard. Es ist nicht standardmäßig installiert (auf den meisten oder allen Distributionen) oder von irgendetwas benötigt, so dass die meisten Leute es nicht haben werden.
Goldlöckchen
3
Ich habe zshauf keinem meiner Systeme installiert, und ich würde es nicht für ein einzelnes Skript installieren. Sie sollten sogar Bashismen vermeiden, obwohl Bash normalerweise verfügbar ist.
Frostschutz

Antworten:

29

Aus Gründen der Portabilität, nein. Es zshkann zwar auf jedem Unix oder Unix-ähnlichen und sogar Windows-System zumindest über Cygwin kompiliert werden und ist für die meisten Open Source-Unix-ähnlichen und mehrere kommerzielle Systeme geeignet. In der Standardinstallation ist es jedoch im Allgemeinen nicht enthalten.

bashAuf der anderen Seite wird es auf GNU-Systemen installiert (genau wie bashdie Shell des GNU-Projekts), wie die große Mehrheit der nicht eingebetteten Linux-basierten Systeme und manchmal auch auf Nicht-GNU-Systemen wie Apple OS / X. Auf der kommerziellen Unix-Seite ist die Korn-Shell (die AT & T-Variante ksh88) die Norm und beides bashund zshist in optionalen Paketen enthalten. Auf dem BSDs ist, ist der bevorzugt interaktiv Shell oft tcshwährend shentweder auf dem Almquist Shell basierte oder pdkshund bashoder zshBedarf als optionale Pakete auch installiert werden.

zshwird standardmäßig unter Apple OS / X installiert. Es war sogar das /bin/shDort. Es ist standardmäßig in einigen Linux-Distributionen wie SysRescCD, Grml, Gobolinux und wahrscheinlich anderen zu finden, aber ich glaube nicht, dass es eine der wichtigsten ist.

Wie für bash, es ist die Frage der installierten Version und infolgedessen die verfügbaren Funktionen. Beispielsweise ist es nicht ungewöhnlich, Systeme mit bash3oder zu finden zsh3. Es gibt auch keine Garantie, dass das Skript, für das Sie jetzt schreiben zsh5, funktioniert, zsh6obwohl bashes versucht, die Abwärtskompatibilität aufrechtzuerhalten.

Für Skripte ist meine Ansicht: Verwenden Sie die POSIX-Shell-Syntax, da alle Unices mindestens eine Shell haben, die aufgerufen wird sh(nicht unbedingt in /bin) und in der Lage ist, diese Syntax zu interpretieren. Dann müssen Sie sich nicht so sehr um die Portabilität kümmern. Und wenn diese Syntax nicht ausreicht, brauchen Sie wahrscheinlich mehr als eine Shell.

Dann haben Sie folgende Möglichkeiten:

  • Perl ist allgegenwärtig (auch hier müssen Sie sich möglicherweise auf die Funktionen alter Versionen beschränken und können keine Annahmen zu den standardmäßig installierten Perl-Modulen treffen).
  • Geben Sie den Interpreter und seine Version (Python 2.6 oder höher, zsh 4 oder höher, bash 4.2 oder höher ...) als Abhängigkeit für Ihr Skript an, indem Sie entweder ein Paket für jedes Zielsystem erstellen, das die Abhängigkeit angibt, oder indem Sie es festlegen in einer README-Datei, die zusammen mit Ihrem Skript geliefert oder als Kommentar am Anfang Ihres Skripts eingebettet wird, oder indem Sie am Anfang Ihres Skripts einige Zeilen in der Bourne-Syntax einfügen, um die Verfügbarkeit des angeforderten Interpreters zu überprüfen und einen expliziten Fehler zu melden Wenn dies nicht der Fall ist, benötigt dieses Skript zsh 4.0 oder höher .
  • Versenden Sie den Interpreter zusammen mit Ihrem Skript (beachten Sie die Auswirkungen auf die Lizenzierung). Dies bedeutet, dass Sie auch ein Paket für jedes Zielbetriebssystem benötigen. Einige Interpreter vereinfachen dies, indem sie die Möglichkeit bieten, das Skript und seinen Interpreter in eine einzige ausführbare Datei zu packen.
  • Schreiben Sie es in einer kompilierten Sprache. Wieder ein Paket pro Zielsystem.
Stéphane Chazelas
quelle
"zsh-man" sagt "nein", ich bin stolz auf dich! ^^ Portabilität ftw! (mit all seinen Vorbehalten ...). +1.
Olivier Dulac
9

Nein, du kannst nicht. Was garantiert verfügbar ist /bin/sh, ist im Wesentlichen die Original-Bourne-Shell. Fast alle (beachten Sie das "fast"!) Linux-Installationen werden bash haben, aber auf * BSD-Systemen ist es selten (die BSD-Persistenz hat ernsthafte Bedenken bezüglich GPL-Code, wie bash). Ich weiß nicht, was die Standard-Shell auf dem Mac ist, aber auch hier gibt es Bedenken bezüglich der GPL. Gleiches gilt für Solaris.

zsh ist eine Nischen-Shell, die nicht in der Standardinstallation von Fedora enthalten ist (und ich glaube nicht, dass es für eine größere Distribution Standard ist).

vonbrand
quelle
6
Sicherlich nicht die ursprüngliche Bourne - Shell, sondern eine Posix - Shell auf Posix - konformen Systemen, die auf vielen Systemen ist / bin / sh, aber nicht unbedingt so (unter Solaris <= Version 10 dieses ist / usr / xpg4 / bin / sh)
Scrutinizer
Nun, die "Standard" -Installation spielt eigentlich keine Rolle. Was zählt ist, ob es überhaupt installiert ist.
Profpatsch
@Profpatsch, dann ist die Standardinstallation sehr relevant (vermutlich hat die Distribution bestimmt, was die Leute wirklich benutzen).
Vonbrand
2
@StephaneChazelas, "Nische" wie in "wenige Benutzer verwenden es" / "wenige Installationen haben es". Es ist vielleicht die beste Schale seit geschnittenem Brot, aber wenn nur ein kleiner Teil davon verwendet wird, kann man nicht zählen, dass sie überall installiert wird.
Vonbrand
1
Beachten Sie, dass, wenn Sie bedenken, dass die große Mehrheit der Linux-Bereitstellungen heutzutage eingebettet ist (z. B. Android, Drucker, Router, Fernseher, Glühbirnen ...), die große Mehrheit der Linux-basierten Systeme nicht über diese Systeme verfügt bash(obwohl diese Systeme wahrscheinlich nicht die Hauptsysteme sind) Ziel, das der OP für seine Frage im Auge hatte)
Stéphane Chazelas
2

Ich denke, es hängt wirklich davon ab, welche zsh- Zusatzfunktionen Sie verwenden und wo. Wenn Sie planen, Ihr Skript auf die verschiedenen Benutzer und Systeme zu verteilen, würde ich vorschlagen, bash oder sogar sh zu verwenden .

Zur gleichen Zeit, wenn Ihr Skript für die organisationsweite Ausführung konzipiert ist und Sie die Konvention haben, zsh auf Ihren Computern zu haben (zum Beispiel dieselbe grundlegende AMI) und Ihre Aufgabe klare Vorteile durch Erweiterungen wie erweiterte Dateiauswahlen oder andere Dinge von http: / /www.rayninfo.co.uk/tips/zshtips.html Ich würde sagen, mach weiter!

AB
quelle
1

Wie bereits erwähnt, bashist dies in der Standardinstallation für viele Distributionen üblich. Ihr Skript erreicht nicht die größte Benutzerbasis, wenn Sie sich auf verlassen zsh.

Eine wichtige Frage, die Sie vor dem Entwerfen Ihres Skripts beantworten müssen, lautet: " Warum spielt es eine Rolle, in welcher Shell ein Skript ausgeführt wird? "

Unterschiedliche Shells verwenden unterschiedliche Syntax oder bieten zusätzliche Shell-Funktionen, die von anderen Shells möglicherweise nicht unterstützt werden. Um ein Skript für die "allgemeine Linux-Endbenutzerwelt" zu schreiben, stellen Sie fest, ob Ihr Skript Syntax- oder Shell-Funktionen verwendet, die von einer bestimmten Shell-Umgebung abhängen.

Beispielsweise unterstützt die bashShell bestimmte Erweiterungen, die von der dashBourne-Shell nicht unterstützt werden oder /bin/shauf die auf dem System des Benutzers verwiesen wird.

$ ls -l /bin/sh 
lrwxrwxrwx 1 root root 4 Feb 19  2014 /bin/sh -> dash

Wenn Sie versuchen, echo {1..10}mit im /bin/shVergleich zu auszuführen , erhalten /bin/bashSie eine sehr unterschiedliche Ausgabe.

Das Gleiche gilt für zshdas, obwohl es die meisten bashSyntaxfunktionen unterstützt, zusätzliche Erweiterungen und Syntaxfunktionen bietet, die von der bashShell nicht unterstützt werden . In diesen Tabellen finden Sie Beispiele für den Vergleich von Schalen .

Sie können Ihre potenzielle Benutzerbasis darüber hinaus erweitern, bashindem Sie Skripts verwenden, die beim Aufrufen mit funktionieren #!/bin/sh -u. Dies wirft jedoch eine weitere wichtige Frage auf: " Was wird im Austausch für mehr Portabilität geopfert? "

Stellen Sie fest, ob Unterschiede in Bezug auf Sicherheitsbedenken, Funktionalität, Effizienz oder andere Aspekte, die Ihrer Meinung nach für Ihr Skript Priorität haben, das Opfer wert sind. Möglicherweise möchten Sie ein Skript mit einer bekannten Sicherheitslücke nicht in großem Umfang verwenden, nur weil es in mehreren Umgebungen funktioniert.

Es sind so viele Skripte dafür geschrieben, bashdass die Unterstützung dieser Skripte als Kriterium beim Vergleich von Befehlsshells verwendet wird . Es können viel mehr Benutzer Ihr Skript ausführen, als wenn es auf zsheiner Shell-Umgebung oder einer anderen Syntax basiert.

Bedenken Sie auch, dass Sie letztendlich keine Kontrolle darüber haben, wie der Benutzer das Skript ausführt (auch nützlich zum Debuggen von Skripten in verschiedenen Shells ):

Denken Sie daran, dass die Shell alle Kommentare am Anfang des Shell-Skripts als Kommentare behandelt, wenn Sie ein Shell-Skript ("sh-Skriptname") lesen, anstatt es direkt auszuführen ("./scriptname"). Insbesondere wird der Kommentar, der den Interpreter angibt, der beim Ausführen des Skripts verwendet werden soll ("#! / Bin / sh -u"), ebenso wie alle Optionen, die neben diesem Interpreter aufgeführt sind, ignoriert.

Das Beste, was Sie dagegen tun können, ist, Ihre Skripte portabel zu machen, solange es keine großen Einbußen bei der Funktionsweise gibt.

Möglicherweise werden auch Konventionen für die Bash-Codierung angezeigt - Stapelüberlauf .

Iyrin
quelle
1
"Was geopfert wird" ... schau auf autoconf. Sie zielen auf / bin / sh ab, wie in "Original Bourne Shell", da alle Shells diese (winzigen) Funktionen unterstützen. Und sie haben sehr darunter gelitten.
Jürgen A. Erhard
1

Das einzige, was Sie fast garantieren können, ist, dass es eine gibt /bin/sh. Dies kann eine statisch verknüpfte Shell oder eine Verknüpfung zu einer anderen Shell sein. Diese andere Shell erkennt normalerweise, dass sie als sh bezeichnet wird, und wird im Kompatibilitätsmodus ausgeführt.

Beachten Sie die fast im ersten Satz.

Jedes Unix-ähnliche System, an dem ich jemals gearbeitet habe, hatte es. Viele von ihnen hatten auch bash installiert (aber nicht alle . Bsp Bash ist nicht standardmäßig auf einigen BSDs installiert. Einige Linux-Distributionen werden mit DASH , der Debian Almquist-Shell, ausgeliefert.

Was Sie garantieren können, sind Ihre Installationsanweisungen. Sie können der README-Datei eine Zeile hinzufügen, in der angegeben wird, dass zsh erforderlich ist. Wenn Sie ein Paket erstellen, können Sie zsh als Abhängigkeit markieren. Sie können dies mit den autoconf / automake-Tools überprüfen. Sie können überprüfen, ob zsh im Installationsskript gefunden wird (starten Sie mit / bin / sh und versuchen Sie, zsh zu finden, falls gefunden, fahren Sie fort. Wenn kein Fehler angezeigt wird, z. B. "Warnung: ZSH ist nicht installiert. Bitte lesen Sie die Installationsanweisungsdatei! ".)

Ich bin sicher, ich habe noch ein paar Optionen vergessen. Die wichtigsten Punkte sind jedoch:

  • Sie können nichts garantieren, bis Sie es überprüft haben.
  • Es ist fast garantiert, dass / bin / sh vorhanden ist und dass Sie dies überprüfen können.
Hennes
quelle
POSIX erfordert / bin / sh, AFAIU. Wie es erfordert ein paar andere sinnvolle Dienstprogramme. Überprüfen Sie die Voraussetzungen der GNU Autoconfiscation.
Vonbrand
@vonbrand. POSIX benötigt nicht /bin/sh. Es erfordert ein Verhalten, shdas sich in der richtigen Umgebung (die nicht die Standardumgebung sein muss) wie angegeben verhält. /bin/shist möglicherweise keine POSIX-Shell. Unter Solaris 10 und früheren Versionen war es beispielsweise noch eine Bourne-Shell, in der der Standard enthalten shwar /usr/xpg4/bin.
Stéphane Chazelas