Welche Shell führt Skripte aus, wenn zu Beginn keine Shebang-Zeile (#! / Path / to / shell) vorhanden ist? Ich gehe von / bin / sh aus, kann es aber nicht bestätigen.
Der Kernel weigert sich solche Skripte und kehrt zur Ausführung ENOEXEC, so dass das genaue Verhalten auf dem Programm hängt führen Sie ein solches Skript aus .
- bash 4.2.39 - benutzt sich selbst
- busybox-ash 1.20.2 - nutzt sich selbst
- Strich 0.5.7 - läuft / bin / sh
- fish 1.23.1 - beschwert sich über ENOEXEC und gibt der falschen Datei die Schuld
- AT & T ksh 93u + 2012.08.01 - nutzt sich selbst
- mksh R40f - Läuft / bin / sh
- pdksh 5.2.14 - Läuft / bin / sh
- sh-heirloom 050706 - nutzt sich selbst
- tcsh 6.18.01 - Läuft / bin / sh
- zsh 5.0.0 - Läuft / bin / sh
- cmd.exe 5.1.2600 - schaut dich komisch an.
Funktioniert in glibcexecv()
oder gibt execve()
einfach ENOEXEC zurück. Aber execvp()
versteckt diesen Fehlercode und ruft automatisch / bin / sh auf. (Dies ist in exec (3p) dokumentiert .)
Was wird als "Best Practices" beim Schreiben von Shell-Skripten angesehen, die auf jeder Plattform ausgeführt werden können? (ok, das ist irgendwie offen)
Halten Sie sich entweder sh
nur an POSIX-definierte Funktionen, oder gehen Sie einfach zu Bash (was allgemein verfügbar ist) und erwähnen Sie es in Ihren Anforderungen, wenn Sie es verteilen.
(Jetzt, wo ich darüber nachdenke, wäre Perl - oder vielleicht Python - noch portabler, ganz zu schweigen von einer besseren Syntax.)
Füge immer die Shebang-Linie hinzu. Verwenden Sie bei Verwendung von bash oder zsh #!/usr/bin/env bash
den Pfad der Shell , anstatt ihn fest zu codieren. (Es ist jedoch garantiert, dass die POSIX-Shell aktiviert ist. /bin/sh
Überspringen Sie env
in diesem Fall.)
(Leider ist sogar /bin/sh
nicht immer dasselbe. Das GNU- Autoconf- Programm muss sich mit vielen verschiedenen Macken auseinandersetzen .)
Ist es möglich, ein Skript zu schreiben, das versucht, zsh zu verwenden und auf bash zurückgreift, wenn zsh nicht verfügbar ist? Ich habe versucht, zwei Shebang-Zeilen zu setzen, wie unten, aber es ist nur ein Fehler mit einem schlechten Interpreter: / bin / zsh: Keine solche Datei oder kein solches Verzeichnis , wenn ich es auf einer Maschine ohne zsh versuche.
Es kann nur eine Shebang-Linie geben. Alles, was nach dem Newline-Zeichen steht, wird nicht einmal vom Kernel gelesen und von Shells als Kommentar behandelt.
Es ist möglich , ein Skript zu schreiben, das als ausgeführt wird #!/bin/sh
, prüft, welche Shell verfügbar ist und ausgeführt wird, exec zsh "$0" "$@"
oder exec bash "$0" "$@"
abhängig vom Ergebnis. Die von bash und zsh verwendete Syntax ist jedoch an verschiedenen Stellen so unterschiedlich, dass ich dies aus Gründen der eigenen Vernunft nicht empfehlen würde .