Ich würde gerne Quelle (dh nicht nennen ) ein Skript von jedem Shell (bash / csh sind die primären Ziele, aber Fisch, zsh, KSH, und rc wäre auch interessant).
Ich möchte, ob das Skript eine einzelne Datei sein kann - dh nicht eine Datei für jeden Shell-Dialekt.
Kann ich das machen?
Ich denke an etwas Ähnliches wie:
if shell is bash then
# bash code here
else
if shell is csh then
# csh code here
else
if shell is xxxsh then
# xxxsh code here
fi
endif
fi
Also kann ich tun:
csh% source my_script
bash$ . my_script
Das Problem ist - natürlich if
ist das nicht in jedem Dialekt gleich, also muss ich irgendwie eine Syntax verwenden, die für jede Shell gültig ist.
Bearbeiten
Das Erkennen der Shell ist der erste Schritt, bei dem das Bestimmen der Shell im Skript zur Laufzeit hervorragende Arbeit leistet.
Ein ebenso wichtiger Schritt ist, wie der Code für die verschiedenen Abschnitte für Shells zitiert werden sollte, um andere Shells nicht zu verwirren. Denken Sie: Wie können Sie im Abschnitt für Bash <<here_document
alle Zeichen in allen Kombinationen enthalten, die in Bash legal, aber in jeder anderen Shell illegal sind, ohne dass dies die anderen Shells verwirrt? Dies wird von keiner der Antworten / verknüpften Antworten abgedeckt.
Antworten:
Anstatt Codefragmente für jede Shell zu schreiben, sollten Sie nur tragbaren Code schreiben, der von den meisten Shells interpretiert werden kann. Sie sollten sich die POSIX Shell-Befehlssprache ansehen . Dies ist ein Standard, wie eine Shell (die POSIX berücksichtigt) Code interpretieren sollte.
Viele Shells
bash
können so konfiguriert werden, dass sie sich wie eine POSIX-Shell verhalten. Jede Shell hat seine gewonnenen Eigenschaften und spezifischen Notationen. Vermeiden Sie sie vollständig in tragbaren Skripten.quelle
csh
das neben seinen vielen anderen Fehlern mit Sicherheit nicht POSIX-konform ist, wird ihnen wahrscheinlich nicht viel helfen.Für csh-like versus Bourne-like können Sie Folgendes tun:
Erklärt:
start=:
würde als Label-Deklaration incsh
und Variablenzuweisung in behandelt werdensh
, also zwei harmlose Operationen.start=:#
, die#
als Kommentar Führer behandelt wirdcsh
, aber nicht in ,sh
da es kein separates Token ist. Also, was danach ist, ist auskommentiert,csh
aber nicht fürsh
.sh
hat einen erfolgreichen Exit-Status (solange die Zuweisungen keine Befehlsersetzungen beinhalten), sodass das Befehlsrecht des||
Operators nicht ausgeführt wird.:<<"goto end="...goto end
Befehl wird nicht ausgeführt, sondern analysiert und ignoriert (die angegebene"goto end"
Anführungszeichen verhindern verschiedene Erweiterungen im Dokument hier). Ein Hinweis jedoch: In der Bourne-Shell (und nur in der Bourne-Shell) wird noch eine temporäre Datei erstellt.goto end=
von der Bourne-ähnlichen Shell ignoriert und von ausgeführtcsh
.goto end=
bewirktcsh
, dass der Teil zwischen diesem undend=:
(eine harmlose Variablenzuweisung in Bourne-ähnlichen Shells) ignoriert wird .Je mehr Shell-Unterstützung Sie hinzufügen, desto schwieriger wird es. Für
fish
besonders, ist es ziemlich schwierig , da es die Syntax des gesamten Skript Ereignis prüft die Teile es nicht ausgeführt.Siehe auch:
parallel
Aufrufen einer Shell hatten)quelle
Ich gehe davon aus, dass der Grund, warum Sie dies tun möchten, die Portabilität ist. Die obigen Antworten geben Ihnen einen Hinweis. Wenn Sie davon ausgehen, dass die Bourne-Shell (sh) der kleinste gemeinsame Nenner ist und "überall" verfügbar ist (Linux, Solaris, Unix, AIX usw.), können Sie
#!/bin/sh
am Anfang Ihres Skripts ein setzen und Ihr gesamtes Skript schreiben mit nur den Funktionen von sh. (Ich denke, dass sh unter Linux nur ein Alias für bash ist, da bash eine Obermenge der Bourne-Shell ist, aber egal, es sollte trotzdem funktionieren.)Eine leichte Verfeinerung ist anzunehmen, dass dies
sh
immer vorhanden ist, aber Sie benötigen möglicherweise die zusätzliche Kraft und Bequemlichkeit einiger der fortschrittlicheren Muscheln. Sie können also eine Version des Skripts für jede der von Ihnen unterstützten Shells schreiben, z. B. script.bash, script.zsh, script.ksh, script.csh usw., wobei jede mit einer eigenen Shebang-Zeile beginnt und dann im Skript. sh Datei würden Sie etwas sagen wie:usw.
Ein weiterer Vorschlag ist, den Quellcode der Auto-Tools-Toolkette zu untersuchen. Die Dinge, die ausgeführt werden, wenn Sie eine ./configure; machen ; make install. Die GNU-Leute haben viele clevere Dinge getan, um sicherzustellen, dass ihre Skripte in allen Umgebungen ausgeführt werden.
quelle
sh
häufig um einen Link zu handeltdash
, aber selbst wenn es sich tatsächlich um einen Link zu handeltbash
, führt das Aufrufenbash
als dazu,sh
dass es im POSIX-Modus ausgeführt wird und sich eher wie herkömmlich verhältsh
alsbash
.