Bash: Execute vs. Source in einem Skript erkennen?

19

Ich besitze ein Skript, das in meinem Dateisystem verstreut ist (Nebeneffekt eines Erstellungsprozesses) und das einige globale Umgebungsvariablen (LD_LIBRARY_PATH, PATH, ROOTDIR usw.) festlegt, die sich für einen ordnungsgemäßen Betrieb in meiner Shell befinden müssen. Das bedeutet natürlich, dass ich es zum source script.shLaufen . script.shbringen muss oder muss und nicht ./script.sh(was eine neue Shell hervorbringen und die Variablen in meiner aktuellen Shell nicht setzen würde).

Kann ich dem Skript irgendetwas hinzufügen, um zu verhindern (oder zu warnen), dass jemand ausgeführt wird ./script.sh?

Yeraze
quelle

Antworten:

15

In einem Shell-Skript $0ist dies der Name des aktuell ausgeführten Skripts. Sie können dies verwenden, um festzustellen, ob Sie wie folgt beschafft oder ausgeführt werden:

if [[ "$(basename -- "$0")" == "script.sh" ]]; then
    echo "Don't run $0, source it" >&2
    exit 1
fi
Mikel
quelle
5

Der einfachste Weg bashist:

if [ "$0" = "$BASH_SOURCE" ]; then
    echo "Error: Script must be sourced"
    exit 1
fi

$BASH_SOURCE Enthält immer den Namen / Pfad des Skripts.

$0 Enthält nur den Namen / Pfad des Skripts, wenn keine Quelle vorhanden ist.

Wenn sie übereinstimmen, bedeutet dies, dass das Skript NICHT bezogen wurde.

weises Glück
quelle
1

Dies wurde auf SO diskutiert . Die am häufigsten aufgerufene Antwort von @barroyo sagt zu verwenden

[[ "${BASH_SOURCE[0]}" != "${0}" ]] && echo "script ${BASH_SOURCE[0]} is being sourced ..."
serv-inc
quelle
@will: Im Handbuch heißt es: Eine Array-Variable, deren Mitglieder die Quelldateinamen sind, in denen die entsprechenden Shell-Funktionsnamen in der Array-Variablen FUNCNAME definiert sind. Wie eine funktion
Serv-Inc
1

Eine andere Option kann das Entfernen von Ausführungsberechtigungen sein. In diesem Fall kann es nicht ausgeführt werden, aber es kann trotzdem bezogen werden.

Jelmer
quelle
1
Dies ist unvollständig. Sie können weiterhin Skripte bash scriptunabhängig vom Ausführungsflag eines Skripts ausführen. Auch unter Cygwin (zählt das?) Kann man Execute Flags nicht wegnehmen.
Tino
0

Zusätzlich zur Prüfung von $ 0 ( Mikel- Antwort) kann es nützlich sein, beispielsweise die Erweiterung von .sh in .src zu ändern. Es wird helfen, jemanden zu verstehen, der dieses Skript nicht ausführen sollte.

Victor Sizov
quelle
0

Erstellen Sie einen benutzerdefinierten Interpreter source_reminder:

#!/bin/sh
printf "%s\n" "Source me!" >&2
exit 1

Vergiss nicht, es ausführbar zu machen. Dann benutze es einfach in deinem Skript:

#!/path/to/your/source_reminder
foo
bar
whatever

Wenn Sie das Skript jetzt ohne Quellenangabe ausführen, erledigt die Erinnerung ihre Aufgabe.

Kamil Maciorowski
quelle
Schöner Fang. #!/bin/echo do not executeoder #!/bin/falseoder #!/usr/bin/awk BEGIN { print "you must source " ARGV[1]; exit(1) }. Dies erfasst jedoch nicht den Fall, dass das Skript mit so etwas ausgeführt wird sh script(da dies den Shebang ignoriert).
Tino