Ich definiere ein Shell-Skript, das ein Benutzer source
ausführen soll, anstatt es auszuführen.
Gibt es eine herkömmliche oder intelligente Möglichkeit, dem Benutzer anzuzeigen, dass dies der Fall ist, beispielsweise über eine Dateierweiterung?
Gibt es Shell-Code, den ich in die Datei selbst schreiben kann, wodurch eine Meldung ausgegeben und die Datei beendet wird, wenn sie anstelle von sourced ausgeführt wird, damit der Benutzer diesen offensichtlichen Fehler vermeiden kann?
x
, das nur den Befehl enthält. your-script-to-be-sourced
, ist dies in Ordnung. Wenn er es jedoch ausführen möchte,bash your-script-to-be-sourced
sollte dies verboten sein. Was ist der Sinn dieser Einschränkung?env
Variablen berechnet und diese als De-facto- Skriptausgabe belässt . Ein Anfänger bleibt tagelang mit dem Rätsel hängen, wenn Sie ihm erlauben, es auszuführen.if __name__ == '__main__'
?Antworten:
Angenommen, Sie führen bash aus, platzieren Sie den folgenden Code in der Nähe des Starts des Skripts, dessen Quelle Sie verwenden möchten, der jedoch nicht ausgeführt wird:
Enthält unter Bash
${BASH_SOURCE[0]}
den Namen der aktuellen Datei, die von der Shell gelesen wird, unabhängig davon, ob sie bezogen oder ausgeführt wird.Im Gegensatz dazu
$0
ist der Name der aktuell ausgeführten Datei.-ef
testet, ob diese beiden Dateien dieselbe Datei sind. Wenn dies der Fall ist, benachrichtigen wir den Benutzer und beenden das Programm.Weder POSIX
-ef
nochBASH_SOURCE
POSIX. Während-ef
von ksh, yash, zsh und Dash unterstützt wird, istBASH_SOURCE
bash erforderlich. Inzsh
jedoch${BASH_SOURCE[0]}
könnte ersetzt werden durch${(%):-%N}
.quelle
echo "Usage: source \"$myfile\""
source
ist nicht portabel. Wenn man bedenkt, dass diese Antwort bash-spezifisch ist, ist es nicht so schlimm, aber es ist eine gute Angewohnheit, das tragbare.
Eine nicht ausführbare Datei kann aus dem Internet bezogen, aber nicht ausgeführt werden. Daher sollte es ein guter Hinweis sein, das Flag für die ausführbare Datei nicht zu setzen.
Edit: Trick, über den ich gerade gestolpert bin: mache den Shebang zu einer ausführbaren Datei, die kein Shell-Interpreter ist, und
/bin/false
lasse das Skript einen Fehler zurückgeben (rc! = 0)quelle
bash somefile.sh
...bash
(vd perl, python, awk ...) ausführen können , dann haben Sie in der Quellesomefile.pl
und Pythonsomefile.py
, also nein, ich habe die Kommentare wahrscheinlich nicht gelesen (was sind das überhaupt?) Undbash somefile.sh
ist kürzer alschmod +x somefile.sh; ./somefile.sh
...bash
, zunächst versuchen ,execve
eine Datei, aber wenn das nicht funktioniert, sie untersuchen die Datei manuell und die manuell zu interpretieren#!
und rufen Sie es durch diesen Interpreter: das ist ein Erbe aus der Zeit , als das#!
war ein rein User - Space Konvention, anstatt vom Kernel selbst gehandhabt zu werden. Ich denkebash
, zumindest werde nicht tue dies für nicht ausführbare Dateien, aber ich weiß nicht , ob es tragbar ist so gesund Verhalten von allen Schalen zu erwarten , dass der Benutzer könnte das Skript aus wird aufgerufen wird .bash
und dasbash script.sh
kann gefährlich sein.In diesem Beitrag zum Stapelüberlauf werden mehrere Methoden vorgeschlagen , von denen mir die von Wirawan Purwanto und mr.spuratic vorgeschlagene funktionsbasierte am besten gefallen hat :
So können Sie am Anfang des Skripts Folgendes hinzufügen:
quelle
Angenommen, es ist nicht schädlich, das Skript auszuführen, können Sie hinzufügen
bis zum Ende des Skripts.
return
außerhalb einer Funktion hat einen Exit-Code ungleich Null, es sei denn, die Datei wird bezogen.quelle
return 2>/dev/null; echo "$0: This script must be sourced" 1>&2; exit 1
Wenn Sie ein Shell-Skript erstellen , wird die Shebang- Zeile ignoriert. Indem Sie einen ungültigen Shebang eingeben, können Sie den Benutzer darauf hinweisen, dass das Skript fälschlicherweise ausgeführt wurde:
Die Fehlermeldung lautet wie folgt:
Der (willkürliche) Argumentname gibt bereits einen starken Hinweis, aber die Fehlermeldung ist immer noch nicht 100% klar. Wir können dies mit einem Hilfsprogramm beheben
source-this-script
, das sich irgendwo in Ihrem befindetPATH
:Nun lautet die Fehlermeldung wie folgt:
Vergleich zu anderen Ansätzen
Im Vergleich zu den anderen Antworten erfordert dieser Ansatz nur minimale Änderungen an jedem Skript (und eine Shebang-Zeile hilft bei der Erkennung von Dateitypen in Editoren und gibt den Shell-Skript-Dialekt an, sodass es sogar Vorteile gibt). Der Nachteil ist eine etwas unklare Fehlermeldung oder das (einmalige) Hinzufügen eines anderen Shell-Skripts.
Es verhindert jedoch nicht den expliziten Aufruf über
bash path/to/script.sh
(danke @muru!).quelle
bash some/script.sh
bietet, der auch den Schebang ignorieren würde.#!/bin/echo 'You must source this script!'
oder so etwas machen.