Bash: обнаружить выполнение против источника в сценарии?


13

У меня есть скрипт, который завален вокруг моей файловой системы (побочный эффект процесса сборки), который устанавливает некоторые глобальные переменные среды (LD_LIBRARY_PATH, PATH, ROOTDIR и т. Д.), Которые должны быть в моей оболочке для правильной работы. Конечно, это означает, что мне нужно source script.sh или же . script.sh заставить его работать, а не ./script.sh (который породил бы новую оболочку и не установил бы переменные в моей текущей оболочке).

Есть ли что-нибудь, что я могу добавить к сценарию? предотвращать (или предупредить) кто-то работает ./script.sh ?

Ответы:


11

В сценарии оболочки $0 это имя запущенного в данный момент скрипта. Вы можете использовать это, чтобы сказать, если вы получаете или бегите так:

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

2

Самый простой способ в bash является:

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

$BASH_SOURCE всегда содержит имя / путь скрипта.

$0 содержит только имя / путь сценария, когда НЕ получены.

Поэтому, когда они совпадают, это означает, что сценарий НЕ был получен.


1

Это обсуждалось на ТАК , самый популярный ответ @barroyo говорит использовать

[[ "${BASH_SOURCE[0]}" != "${0}" ]] && echo "script ${BASH_SOURCE[0]} is being sourced ..."

@будут: Руководство говорит: переменная массива, членами которой являются имена файлов источника, где определены соответствующие имена функций оболочки в переменной массива FUNCNAME. Как функция?
serv-inc

1

Чтобы обнаружить случаи, когда скрипт вызывается из другого каталога, вы должны использовать basename на обоих, $0 а также ${BASH_SOURCE[0]}, Понятно, что это башизм, поэтому другие оболочки должны измениться ${BASH_SOURCE[0]} к соответствующей переменной.

#!/bin/bash
if [[ $(basename -- "$0") == $(basename -- "${BASH_SOURCE[0]}") ]]; then
  echo "Sourcing the script (${BASH_SOURCE[0]})" >&2
  source "${BASH_SOURCE[0]}"
  exit 0;
fi

1

Другим вариантом может быть удаление разрешений на выполнение. В этом случае он не может быть выполнен, но он все еще может быть получен.


0

Создать пользовательский переводчик source_reminder:

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

Не забудьте сделать его исполняемым. Затем просто используйте его в своем исполняемом скрипте:

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

Теперь, если вы запустите скрипт без поиска источников, напоминание выполнит свою работу.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.