Bash: wykryć wykonanie skryptu względem źródła?


19

Mam skrypt zaśmiecony wokół mojego systemu plików (efekt uboczny procesu kompilacji), który ustawia niektóre globalne zmienne środowiskowe (LD_LIBRARY_PATH, PATH, ROOTDIR itp.), Które muszą znajdować się w mojej powłoce, aby poprawnie działać. Oczywiście oznacza to, że muszę to zrobić source script.shlub . script.shsprawić, by działało, a nie ./script.sh(co spowoduje odrodzenie nowej powłoki i nie ustawianie zmiennych w mojej bieżącej powłoce).

Czy jest coś, co mogę dodać do skryptu, aby zapobiec (lub ostrzec) przed uruchomieniem ./script.sh?

Odpowiedzi:


15

W skrypcie powłoki $0jest nazwą aktualnie uruchomionego skryptu. Możesz użyć tego, aby określić, czy jesteś pozyskiwany, czy biegać w ten sposób:

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

5

Najprostszym sposobem bashjest:

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

$BASH_SOURCE zawsze zawiera nazwę / ścieżkę skryptu.

$0 zawiera tylko nazwę / ścieżkę skryptu, gdy NIE jest pozyskiwany.

Kiedy więc się zgadzają, oznacza to, że skrypt NIE został pobrany.



1

Inną opcją może być usunięcie uprawnień do wykonywania. W takim przypadku nie można go wykonać, ale nadal można go uzyskać.


1
To jest niekompletne. Nadal możesz uruchamiać skrypty bash scriptniezależnie od flagi wykonania na skrypcie. Również pod Cygwin (czy to się liczy?) Nie można zabrać flag wykonawczych.
Tino

0

Oprócz sprawdzenia $ 0 ( odpowiedź Mikela ) może być przydatna na przykład zmiana rozszerzenia z .sh na .src. Pomoże to zrozumieć każdego, kto nie powinien wykonać tego skryptu.


0

Utwórz niestandardowego interpretera source_reminder:

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

Nie zapomnij, aby był wykonywalny. Następnie użyj go w skrypcie:

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

Teraz, jeśli uruchomisz skrypt bez źródła, przypomnienie wykona swoją pracę.


Dobry chwyt. #!/bin/echo do not executelub #!/bin/falselub #!/usr/bin/awk BEGIN { print "you must source " ARGV[1]; exit(1) }. Jednak nie wychwytuje to przypadku, w którym skrypt jest wykonywany z czymś podobnym sh script(ponieważ ignoruje to Shebang).
Tino
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.