GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Wann muss ich #!/bin/bash und wann #!/bin/sh verwenden?

Kurz:

  • Es gibt mehrere Shells, die eine Obermenge der POSIX-sh-Spezifikation implementieren. Auf anderen Systemen /bin/sh könnte ein Link zu ash, bash, dash, ksh, zsh usw. sein. (Es wird jedoch immer sh-kompatibel sein – niemals csh oder fish.)

  • Solange Sie sich an sh halten nur Funktionen, können (und sollten Sie wahrscheinlich sogar) #!/bin/sh verwenden und das Skript sollte gut funktionieren, egal um welche Shell es sich handelt.

  • Wenn Sie beginnen, Bash-spezifische Funktionen (z. B. Arrays) zu verwenden, sollten Sie bash ausdrücklich anfordern – denn selbst wenn /bin/sh ruft bash bereits auf Ihrem auf System, möglicherweise nicht auf allen anderen System, und Ihr Skript wird dort nicht ausgeführt. (Dasselbe gilt natürlich für zsh und ksh.) Sie können Shellcheck verwenden, um Bashismen zu identifizieren.

  • Auch wenn das Skript nur für den persönlichen Gebrauch bestimmt ist, stellen Sie möglicherweise fest, dass einige Betriebssysteme /bin/sh ändern bei Upgrades – z.B. Unter Debian war es früher bash, wurde aber später durch ein sehr minimales Bindestrich ersetzt. Skripte, die Bashismen verwendeten, aber #!/bin/sh hatten plötzlich kaputt.

Allerdings:

  • Sogar #!/bin/bash ist nicht ganz korrekt. Auf anderen Systemen befindet sich bash möglicherweise in /usr/bin oder /usr/pkg/bin oder /usr/local/bin .

  • Eine zuverlässigere Option ist #!/usr/bin/env bash , die $PATH verwendet. (Obwohl die env Das Tool selbst ist auch nicht streng garantiert, /usr/bin/env funktioniert immer noch auf mehr Systemen als /bin/bash tut.)


Verwenden Sie den Shebang, der der Shell entspricht, die Sie tatsächlich zum Entwickeln und Debuggen Ihres Skripts verwendet haben. Dh wenn Ihre Login-Shell bash ist , und Sie führen Ihr Skript als ausführbar in Ihrem Terminal aus, verwenden Sie #!/bin/bash . Gehen Sie nicht einfach davon aus, da Sie keine Arrays (oder was auch immer bash Funktion, die Ihnen bekannt ist), können Sie sicher die Shell auswählen, die Sie mögen. Es gibt viele subtile Unterschiede zwischen Shells (echo , Funktionen, Schleifen, wie Sie es nennen), die ohne angemessene Tests nicht entdeckt werden können.

Beachten Sie Folgendes:Wenn Sie #!/bin/bash verlassen und Ihre Benutzer haben es nicht, sehen sie eine klare Fehlermeldung, etwa so wie

Error: /bin/bash not found

Die meisten Benutzer können dies in weniger als einer Minute beheben, indem sie das entsprechende Paket installieren. Andererseits, wenn Sie den Shebang durch #!/bin/sh ersetzen und testen Sie es auf einem System, auf dem /bin/sh ist ein symbolischer Link zu /bin/bash , Ihre Benutzer, die bash nicht haben wird in Schwierigkeiten geraten. Sie sehen höchstwahrscheinlich eine kryptische Fehlermeldung wie:

Error in script.sh line 123: error parsing token xyz

Es kann Stunden dauern, dies zu beheben, und es gibt keinen Hinweis darauf, welche Shell sie hätten verwenden sollen.

Es gibt nicht viele Gründe, warum Sie eine andere Schale im Shebang verwenden möchten. Ein Grund dafür ist, dass die von Ihnen verwendete Shell nicht weit verbreitet ist. Eine andere Möglichkeit besteht darin, mit sh an Leistung zu gewinnen was auf einigen Systemen deutlich schneller ist, UND Ihr Skript wird ein Leistungsengpass sein. Testen Sie in diesem Fall Ihr Skript gründlich mit der Ziel-Shell und ändern Sie dann den Shebang.


Sie sollten immer nur #! /bin/sh verwenden .

Sie sollten niemals bash- (oder zsh- oder fish- oder ...) Erweiterungen in einem Shell-Skript verwenden.

Sie sollten immer nur Shell-Skripte schreiben, die mit beliebigen funktionieren Implementierung der Shell-Sprache (einschließlich aller "Hilfs"-Programme, die mit der Shell selbst einhergehen). Heutzutage können Sie das wahrscheinlich nimm POSIX.1-2001 (nicht -2008) als maßgeblich dafür, wozu die Shell und die Dienstprogramme in der Lage sind, aber seien Sie sich bewusst, dass Sie eines Tages aufgefordert werden könnten, Ihr Skript auf ein Altsystem (z. B. Solaris oder AIX) zu portieren, dessen Shell und Dienstprogramme um 1992 eingefroren wurden.

Was, ernsthaft?!

Ja, im Ernst.

Hier ist die Sache:Shell ist schrecklich Programmiersprache. Das Einzige, was dafür spricht, ist /bin/sh ist der einzige Skriptinterpreter, der jeder Unix-Installation ist garantiert vorhanden.

Hier ist die andere Sache:eine Iteration des zentralen Perl 5-Interpreters (/usr/bin/perl ) ist mehr wahrscheinlich auf einer zufällig ausgewählten Unix-Installation verfügbar als (/(usr|opt)(/(local|sfw|pkg)?)?/bin/bash ist. Andere gute Skriptsprachen (Python, Ruby, node.js usw. – ich zähle sogar PHP und Tcl in diese Kategorie, wenn ich sie mit Shell vergleiche) sind ebenfalls ungefähr so ​​​​verfügbar wie Bash und andere erweiterte Shells.

Wenn Sie also die Möglichkeit haben, ein Bash-Skript zu schreiben, haben Sie stattdessen die Möglichkeit, eine Programmiersprache zu verwenden, die nicht schrecklich ist.

Nun, einfach Shell-Skripten, die nur ein paar Programme in einer Sequenz von einem Cron-Job oder so etwas ausführen, ist nichts falsch daran, sie als Shell-Skripte zu belassen. Aber einfache Shell-Skripte brauchen keine Arrays oder Funktionen oder [[ eben. Und Sie sollten nur kompliziert schreiben Shell-Skripte, wenn Sie keine andere Wahl haben. Autoconf-Skripte zum Beispiel sind eigentlich immer noch Shell-Skripte. Aber diese Skripte müssen auf allen ausgeführt werden Inkarnation von /bin/sh das ist relevant für das zu konfigurierende Programm. und das bedeutet, dass sie keine Erweiterungen verwenden können. Sie müssen sich heutzutage wahrscheinlich nicht mehr um alte proprietäre Unixe kümmern, aber Sie sollten es wahrscheinlich sollten kümmern sich um aktuelle Open-Source-BSDs, von denen einige bash nicht installieren standardmäßig und eingebettete Umgebungen, die Ihnen nur eine minimale Shell und busybox bieten .

Zusammenfassend, der Moment, in dem Sie feststellen, dass Sie wollen eine Funktion, die in der portablen Shell-Sprache nicht verfügbar ist, das ist ein Zeichen dafür, dass das Skript zu kompliziert geworden ist, um ein Shell-Skript zu bleiben. Schreiben Sie es stattdessen in einer besseren Sprache um.


Linux
  1. /usr/bin vs. /usr/local/bin Unter Linux?

  2. Bash =~ Regex und Https://regex101.com/?

  3. Linux – Zusammenführen von /usr/bin und /usr/sbin in /bin (gnu/linux)?

  4. Installieren Sie Binärdateien in /bin, /sbin, /usr/bin und /usr/sbin, Interaktionen mit --prefix und DESTDIR

  5. #!/bin/sh vs. #!/bin/bash für maximale Portabilität

cmake --version zeigt auf /usr/bin/cmake, während cmake auf /usr/local/bin zeigt

Wann sollte ich /dev/shm/ verwenden und wann sollte ich /tmp/?

Was bedeuten /usr/sbin, /usr/local/sbin und /usr/local/bin?

Unterschied zwischen /bin und /usr/bin

/bin Inhalt nach /usr/bin verschoben, rückgängig machen möglich?

Sollten Websites gemäß der empfohlenen Verwendung in /var/ oder /usr/ leben?