Richtige Methode zum Verteilen von Shell-Skripten


8

Was ist der beste Weg, um Shell-Skripte zu verteilen, wenn das Verhalten von Shells durch geändert werden kann setund daher unvorhersehbar ist?

Wird beispielsweise rm *.txtin den Umgebungen, in denen es ausgeführt wurde , nicht wie erwartet set -fausgeführt. Wie soll ich sicherstellen, dass rm *.txtin allen Umgebungen alle Textdateien in einem aktuellen Verzeichnis entfernt werden?

Wie kann ich sicherstellen, dass Shell-Skripte wie erwartet ausgeführt werden, bevor sie allgemein verteilt werden?


shell_state=$(set +o) ... Skript ...eval "$shell_state"
Mikeserv

Sie können diese Befehle oben im Skript selbst ausführen oder die ändern, #!um anzugeben, welche Shell-Optionen Sie möchten.
HalosGhost

Antworten:


6

Shell-Skripte werden normalerweise so behandelt, als wären sie mit jeder anderen Art von ausführbarer Datei identisch, z. B. Binärdateien, Python-Skripten, Perl-Skripten oder anderen Skripten. Sie haben oben einen Shebang , der den Kernel anweist, sie durch die Shell auszuführen. Es wird erwartet, dass sie wie jeder andere Befehl aufgerufen werden.

Daher wird bei jedem Aufruf des Skripts eine neue Shell gestartet, und Einstellungen, wie set -fsie in der aufrufenden Shell oder in einer anderen Shell-Instanz im System vorhanden sind, sind irrelevant.

Natürlich können Benutzer Ihr Skript als Quelle ausführen, anstatt es auszuführen, zum Beispiel wie folgt:

. /path/to/your/script

oder um es in einer Shell auszuführen, die nicht standardmäßige Einstellungen wie diese hat:

sh -f /path/to/your/script

Dies wird jedoch nicht als normale Methode oder als Aufruf Ihres Skripts angesehen, und Benutzer, die dies tun, sollten erwarten, was auch immer sie als Ergebnis erhalten.

Beachten Sie, dass es einige Skripte gibt, die beschafft und nicht ausgeführt werden sollen, da sie beispielsweise dazu dienen, das cwd zu ändern oder Umgebungsvariablen festzulegen, die in der Umgebung der Sourcing-Shell berücksichtigt werden müssen. Diese Skripte sind jedoch in der Minderheit und es wird normalerweise als Teil eines vereinbarten Protokolls durchgeführt. Diese Dateien können eher als "Plugins" für jedes System betrachtet werden, von dem sie erwartet werden, und nicht als unabhängige Skripte. Beispielsweise werden Dateien /etc/rc*.dmit Namen, die auf enden, .shvom Startskript-Subsystem bezogen und nicht ausgeführt. Es wird dokumentiert, dass dies der Fall ist, wenn Sie eine Datei mit einem solchen Namen in platzieren/etc/rc*.dund wenn es fertig ist, ist es absichtlich gemacht. Die Konvention, Dateien zu benennen, die beschafft und nicht auf diese Weise ausgeführt werden sollen, wird auch an anderer Stelle befolgt, jedoch nicht allgemein.

Es ist richtig, dass Dateien, die auf diese Weise bezogen werden sollen, darauf achten müssen, welche Einstellungen in der Umgebung ihres Anrufers vorhanden sein können, die sich auf das Verhalten der Shell auswirken können. Dann sollte das vereinbarte Protokoll jedoch idealerweise eine vorhersehbare Ausführungsumgebung versprechen.


1
zshverfügt über eine Funktion, mit der die Optionen in einem Know-Set in einem lokalen Kontext ( emulate -L zsh) wiederhergestellt werden können, das in allen mit zsh gelieferten und als zsh-Code geschriebenen Erweiterungen häufig verwendet wird. Sehen Sie, wie das Bash-Vervollständigungssystem kläglich ausfällt, wenn Sie einige Optionen wie z failglob.
Stéphane Chazelas

Einige Shells lesen Ihre Anpassungsdatei auch dann, wenn sie zur Interpretation von Skripten aufgerufen werden. Deshalb verwenden Sie in der Regel #! /bin/csh -fstatt #! /bin/cshzum Beispiel.
Stéphane Chazelas

@ StéphaneChazelas Haha, ja in der Tat. Das ist natürlich ein Grund , warum die Verwendung von csh eine schlechte Idee ist , oder? :-) Aber ich denke, zsh hat das auch in Form von zshenv. Pass auf, was du zshenvaus diesem Grund eingegeben hast !
Celada

@ StéphaneChazelas übrigens, es ist nicht das erste Mal, dass du mir etwas beibringst, was ich ( emulate -Lin diesem Fall) nicht wusste, indem du eine meiner Antworten kommentierst, und ich weiß das zu schätzen.
Celada

Nun, ~/.zshenv(wo Sie Einstellungen (im Allgemeinen env vars) für alle zshs (interaktiv oder nicht) erzwingen möchten, die unter Ihrem Namen aufgerufen werden und im Allgemeinen nicht verwendet werden, außer um ein anderes Nicht-zsh-Problem zu umgehen) ist getrennt von ~/.zshrc(interaktiv) Anpassungsshell), also ist es eine Funktion, kein Fehler. (Sie können zsh -f verwenden) Ein Fehler ist, wenn einige nicht interaktive Bash-Shells Ihre lesen ~/.bashrc(wie über ssh und Sie müssen Code hinzufügen, um sich davor zu schützen) oder wenn eine interaktive Bash (die Login-Shells) sie nicht lesen (und wieder müssen Sie Code hinzufügen, um das Problem zu umgehen ~/.bash_profile).
Stéphane Chazelas
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.