Wie kann ich die POSIX-Kompatibilität von Shell-Skripten testen?

72

In Anbetracht der Tatsache, dass POSIX einem gemeinsamen Standard unter allen Unices am nächsten kommt, möchte ich wissen, ob es eine Shell gibt, die es ausschließlich unterstützt. Während die meisten modernen Shells POSIX unterstützen (und POSIX-kompatible Skripte problemlos ausführen), können sie nicht gut auf nicht kompatible Funktionen hinweisen.

Gibt es eine Shell, die nur POSIX und POSIX so implementiert, dass bei nicht kompatiblen Funktionen ein Fehler ausgegeben wird?

BEARBEITEN Ich möchte klarstellen, dass ich nicht nach allgemeinen Tipps zum Schreiben von portablen Shell-Skripten frage. Die entsprechende Frage, die in den Kommentaren erwähnt wurde, deckte dies bereits ab. Ich dachte an diese Frage, als ich herausfand, dass bashes eine --posixOption gibt, aber nur um herauszufinden, dass sie nur einige Initialisierungsverhalten betrifft, was nicht genau das ist, wonach ich suche.

rahmu
quelle
@Gilles: Vielleicht sollte ich erwähnen, dass ich auf diese Frage gestoßen bin, aber nur eine Antwort schlug das Testen mit vor dash. Ich erwähnte Portabilität als allgemeinen Kontext für meine Frage, aber das war nicht die wahre Absicht.
Rahmu
Klar, ich wollte, dass die beiden Fragen miteinander verknüpft werden, da sie wahrscheinlich für die gleichen Personen von Interesse sind. Sie sind keineswegs Duplikate. Posh ist übrigens ein besserer Test für die POSIX-Konformität als Dash.
Gilles
2
busybox kommt nur POSIX und POSIX sehr nahe. Eine Sache, die Sie stören kann, ist, wenn Sie auch andere Pakete (wie diffutils) installieren, dann können Funktionen hinzugefügt werden. Checkout Live-CD von Alpine Linux , die Sie in eine reine Busybox-Umgebung entführt. Alpine verwendet die musl C-Bibliothek, sodass Sie keine GNU-Erweiterungen erhalten, die Funktionen wie erweiterte reguläre Ausdrücke hinzufügen können.
Michael Fox

Antworten:

37

Leider ist 'portabel' für Shellskripte in der Regel eine höhere Anforderung als 'POSIX-konform'. Das heißt, etwas zu schreiben, das auf einer POSIX-Shell läuft, ist nicht allzu schwierig, aber es ist schwieriger, es auf einer echten Shell laufen zu lassen.

Sie können damit beginnen, jede Shell in Ihrem Paketmanager zu installieren, insbesondere Debians poshSounds, die Ihren Wünschen entsprechen (Policy-konforme Ordinary SHell). Debians Richtlinie ist POSIX mit wenigen Ausnahmen ( echo -nangegeben, local...).

Darüber hinaus müssen einige Shells (insbesondere / bin / sh) auf verschiedenen Plattformen getestet werden. Ich teste auf Solaris (/ bin / sh und xpg4 / sh) und BSD. AIX und HP-UX sind sehr kompatibel und verursachen keine Probleme. Bash ist eine kleine Welt für sich.

Ich würde den Autoconf-Leitfaden für tragbare Shell empfehlen , der absolut brillant ist und viel Zeit spart. Große Teile davon sind veraltet, aber das ist in Ordnung. überspringe einfach TruUnix und Ultrix und so weiter, wenn es dir egal ist!

Nicholas Wilson
quelle
poshklingt in der Tat wie das, wonach ich bitte. Ich werde einige Tests machen, sobald ich kann.
Rahmu
1
Ich antwortete, bevor ich die entsprechende Frage entdeckte! Posh ist eine Debian-Sache, wird also nicht auf jedem System gepackt. Außerdem ist die Shell nicht unbedingt das, worüber man sich am meisten Sorgen machen muss. Beispielsweise sind sed-Inkompatibilitäten ein großes Problem.
Nicholas Wilson
Ich würde mich nicht darum kümmern, auf die Solaris / bin / sh aka Bourne-Shell (die nicht POSIX ist) zu portieren. Solaris wie alle modernen Unices hat eine POSIX-Shell, es ist einfach nicht an der üblichen Stelle (/ usr / xpg4 / bin / sh)
Stéphane Chazelas
Leider liefern wir Skripte aus, die mindestens auf jedem / bin / sh laufen müssen. Es ist nicht so schlimm wie das alles ... Ich würde es aber lieber nicht tun müssen.
Nicholas Wilson
2
Der Grund, warum ich / bin / sh als wichtig betrachte, ist, dass es in so vielen Skripten vom shebang aufgerufen wird. "/ usr / bin / env sh" ist kaum eine Verbesserung. Wenn Sie sich die Mühe machen, dass etwas mit Nicht-POSIX-Shells funktioniert, kann ich meines Erachtens auch jedem System / bin / sh Priorität einräumen. Es wird nicht lange dauern, bis ein Kunde Ihr Skript mit der Standard-Shell ausführt, was nicht allzu unvernünftig ist.
Nicholas Wilson
28

Sie können ShellCheck (GitHub) als Linter für Ihre Shell-Skripte verwenden. Es gibt auch eine Online-Version .

Um POSIX-Kompatibilitätsprobleme zu erkennen (z. B. SC2039 ), sollte die shebang-Zeile Ihres Shell-Skripts lauten #!/bin/sh. Sie können auch --shell=shan übergeben shellcheck.

Beispiel ( test.sh):

#!/bin/sh
if [[ $HOSTNAME == test ]]; then
    echo fail &> foo
fi

Ergebnis ( shellcheck test.sh):

In test.sh line 2:
if [[ $HOSTNAME == test ]]; then
   ^-- SC2039: In POSIX sh, [[ ]] is undefined.
      ^-- SC2039: In POSIX sh, HOSTNAME is undefined.    

In test.sh line 3:
    echo fail &> foo
              ^-- SC2039: In POSIX sh, &> is undefined.
johnLate
quelle
1
In all den Jahren habe ich noch nie von ShellCheck gehört ... danke für den Link!
Ton van den Heuvel
Bestes Werkzeug aller Zeiten! Vor allem mit einer Online-Version ist es fantastisch, schnell einen Code zu überprüfen!
Mecki
12

Bash wird im POSIX-kompatiblen Modus ausgeführt, wenn die POSIXLY_CORRECTUmgebungsvariable festgelegt ist. Aus der Manpage:

   POSIXLY_CORRECT
          If  this  variable  is  in the environment when bash starts, the
          shell enters posix mode before reading the startup files, as  if
          the  --posix  invocation option had been supplied.  If it is set
          while the shell is running, bash enables posix mode, as  if  the
          command set -o posix had been executed.

Viele andere GNU-Dienstprogramme werden ebenfalls berücksichtigt POSIXLY_CORRECT. Wenn Sie also auf einem System mit überwiegend GNU-Tools (z. B. den meisten Linux-Systemen) arbeiten, ist dies ein guter Anfang, wenn Sie POSIX-Konformität anstreben.

James Sneeringer
quelle
21
Sogar im POSIX-Modus lässt bash einige Nicht-POSIX-Funktionen zu, z [[.
Jordanien