Shell-Skript-Header für beste Kompatibilität [Duplikat]

Diese Frage hat hier bereits Antworten :

Kommentare

  • Es geht wirklich darum, wie portabel Sie sein möchten . Nur Unixe? Alle Linux-Kernel-basierten Boxen? Alle Systeme auch alte Win 3.0 und VMS (Scherz)? /bin/sh ist normalerweise ein gutes Minimum. Beachten Sie jedoch, dass sh nicht bash ist. Erwarten Sie auf den meisten GNU / Linux -Systemen.
  • Obwohl Android den Linux-Kernel verwendet und die Standard-Shell von Bash via Ash abgeleitet ist, ist das Userland nicht Sehr unixartig und es fehlen viele Standardwerkzeuge.

Antwort

Aus Gründen der Portabilität können Sie davon ausgehen, dass #!/bin/sh findet auf jedem Standard-Unix- oder Linux-System eine größtenteils POSIX-kompatible Shell, aber das ist wirklich alles.

In FreeBSD, OpenBSD und NetBSD ( zusammen mit DragonFly, PC-BSD und einigen anderen Derivaten befindet sich bash unter /usr/local/bin/bash (falls installiert), also /usr/bin/env Der Ansatz bietet Portabilität zwischen Linux und BSD.

Android ist kein Standard-Unix- oder Linux-System. Auf meinem nicht gerooteten Android-Telefon ist keines von /usr/bin/env, /bin/bash o r sogar /bin/sh existiert, und die System-Shell ist /system/bin/sh.

Ein Shell-Skript, dem das #! (shebang) versucht, in der Shell ausgeführt zu werden, die es auf einigen Systemen aufgerufen hat, oder verwendet möglicherweise einen anderen Standardinterpreter (/bin/bash zum Beispiel). auf anderen Systemen. Und obwohl dies unter Android funktioniert, kann nicht garantiert werden, dass es unter anderen Betriebssystemen funktioniert, bei denen Benutzer möglicherweise eine interaktive Shell verwenden, die nicht bash. (Ich verwende tcsh in FreeBSD, wo es die Standard-Shell ist, und shebang-less-Skripte werden von der aufrufenden Shell interpretiert.)

Von meinem Platz aus sieht es also so aus, als wäre es kann kein Shell-Skript erstellen, das zwischen Android- und Nicht-Android-Systemen (Linux oder Unix) portierbar ist, da Android die Dinge anders macht.

Kommentare

  • Nach meiner Erfahrung soll /bin/sh eher auf bsh oder dash als bash, das relativ aufgebläht ist und daher für die interaktive Verwendung bevorzugt wird.
  • Einige Fehler hier. Es gibt immer noch viele (meist kommerzielle) Einheiten hier (die meisten davon Solaris 10 und früher), in denen /bin/sh das Bourne-Regal ist l, keine POSIX-Shell, gibt POSIX ' den Pfad von sh nicht an. Die meisten Shells (und execp / env / find -exec...) interpretieren einen She-Bang- Weniger Skript mit dem System ' s sh, nur wenige interpretieren es mit sich selbst und wenn, dann im POSIX-Kompatibilitätsmodus. Das ' ist die Standard- / POSIX-Methode zum Ausführen von Skripten, setzt jedoch voraus, dass sich der Aufrufer in einer POSIX-Umgebung befindet.
  • In Bezug auf * BSD bash ist optional. Dies bedeutet, dass gute Chancen bestehen, dass selbst /usr/local/bin/bash auf den Systemen nicht vorhanden ist (ganz zu schweigen von proprietären Systemen wie Solaris, AIX oder HP-Ux).
  • @ StephaneChazelas – bezüglich POSIX stimme ich natürlich zu, und aus diesem Grund waren ' die von mir verwendeten Wörter " größtenteils POSIX-konform ". Bei dieser Frage ging es jedoch eher um die Portabilität als darum, wo POSIX zu finden ist, und man kann sich ' nicht darauf verlassen, dass eine Shell immer an einem Ort gefunden wird. In Bezug auf den Standardinterpreter wird ein in tcsh ausgeführtes Skript ohne Shebang von tcsh unter FreeBSD interpretiert. Offensichtlich gibt es dort auch ' Inkonsistenz, daher habe ich ' die Antwort entsprechend aktualisiert.
  • @Ouki – Ja, natürlich habe ich ' nicht gedacht, dass dies für die Frage relevant ist. Aber ich ' habe diese Klarstellung der Klarheit halber hinzugefügt.

Antwort

Nach meiner Erfahrung haben #!/bin/sh und #!/bin/bash auf den wenigen Systemen, an denen ich gearbeitet habe, immer die richtige Umgebung gefunden . Ich bin noch nicht auf eine Ausnahme gestoßen. Ich finde es auch routinemäßig in Shell-Scripting-bezogenen Texten verwendet, von denen ich annehme, dass sie unter Berücksichtigung der Portabilität aufgrund unterschiedlicher Zielgruppen geschrieben wurden.

Kann mit #!/usr/bin/env.Einige Systeme haben es als #!/bin/env installiert und meine Python-Skripte in der Vergangenheit beschädigt. Also werde ich mit dem zweiten Aufzählungszeichen fortfahren.

Hier ist eine Unterstützung für meine obige Aussage:

In CentOS Release 5.7 erhalte ich Folgendes:

$ which env /bin/env 

Unter Ubuntu 12.04 Präzises Pangolin:

$ which env /usr/bin/env 

Außerdem erinnere ich mich zumindest in einem älteren System an die Administratoren coreutils auf /opt aus irgendeinem Grund installiert (möglicherweise keine bewährte Methode). Da env ist Teil von coreutils, Benutzer haben es schließlich bei /opt/coreutils/bin/env erhalten. Zugegeben, ich habe nicht alle Systeme da draußen verwendet, also die Antwort basiert auf meiner begrenzten Erfahrung.

Kommentare

  • Zum Beispiel ist /bin/bash definitiv nicht FreeBSD (würde /usr/local/bin/bash sein, da bash nicht Teil der Standard-Shells ist.
  • ' ist eher das Gegenteil: nur einigen sehr seltenen Systemen fehlt /usr/bin/env (SCO, was barel ist y vorhanden, NextStep, das so gut wie ausgestorben ist – und natürlich die gängigsten Nicht-Unix-Systeme wie Android oder Windows). Andererseits existiert /bin/bash so ziemlich nur unter nicht eingebettetem Linux. /bin/sh ist eine sichere Wette auf jedes Unix, aber einige ältere Systeme haben dort eine Nicht-POSIX-Bourne-Shell.
  • @Gilles Vielen Dank für die Informationen. Ich habe meine Antwort aktualisiert und einige Beweise dafür geliefert, was ich auf einigen Systemen gesehen habe, auf die ich gestoßen bin.
  • which env isn ' t relevant: Es gibt einige Systeme, in denen /usr/bin ein Symlink zu /bin ist oder umgekehrt, wodurch beide /usr/bin/env und /bin/env verwendbar. Was zählt, ist, dass /usr/bin/env vorhanden ist, was bei allen Linux-Distributionen der Fall ist, von denen ich ' jemals gesehen oder gehört habe (und die entfernt wurden) würde so viele Dinge zerbrechen, dass niemand es tun würde).

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.