Я определяю сценарий оболочки, который пользователь должен источник
, а не казнить.
Есть обычный или интеллектуальный способ намекнуть пользователю, что это тот случай, например, через расширение?
Есть код оболочки я могу писать в сам файл, что приведет к его эхо-сообщение и выход, если он выполняется вместо источников, так что я могу избежать этой очевидной ошибки?
Предполагая, что вы используете Баш, поместите следующий код в начале скрипта, который вы хотите быть получены, но не исполнены:
if [ "${BASH_SOURCE[0]}" -ef "$0" ]
then
echo "Hey, you should source this script, not execute it!"
exit 1
fi
Под Баш, ${BASH_SOURCE[0]}
будет содержать имя текущего файла, что оболочка-это значение, независимо от того, получены или казнены.
В отличие от этого, $0
- это имя текущего файла выполняется.
-эф
тесты, Если эти два файла один и тот же файл. Если они есть, мы предупреждаем пользователя и выход.
Ни -эф", ни " BASH_SOURCE не в POSIX. В то время как
-эфподдерживается КШ, Яша, zsh и тире,
BASH_SOURCE требует Баш. В ЗШ
, однако, ${BASH_SOURCE[0]}
можно заменить ${(%):-%Н}
.
Файл не является исполняемым, могут быть получены, но не исполнены, поэтому, в качестве первой линии обороны, не установив исполняемый флаг должен быть хороший намек...
Редактировать: я просто наткнулся на: сделайте такое быть любой исполняемый файл, что это'т интерпретатор командной строки, /Бен/значение false
делает скрипт возвращает ошибку (ГС!=0)
#!/bin/false "This script should be sourced in a shell, not executed directly"
Существует несколько методов, предложенных в этот переполнение стека пост, из которых, мне понравилась функция на основе предложенного Wirawan Purwanto и МР.spuratic лучший:
самый надежный способ, как полагают Wirawan Purwanto, чтобы проверить
ИМЯ_ФУНКЦИИ[1]
внутри функции:mycheck функция() { заявляю-Р ИМЯ_ФУНКЦИИ; } mycheck
тогда:
$ Баш sourcetest.sh объявить-ИМЯ_ФУНКЦИИ='([0]=&я mycheck-то" 1="и главное")' и GT; $ . sourcetest.sh объявить-ИМЯ_ФУНКЦИИ='([0]=&я mycheck-то" 1=на"источник" в)'
Это эквивалентно проверки вывода вызывающим значения
main
иисточник
отличить абонента'ы контексте. ИспользуяИМЯ_ФУНКЦИИ[]
экономит захвата и анализа вызывающим выход. Вам нужно , Чтобы узнать или рассчитать свой локальный глубину вызова хоть и правильные. Случаях как сценарий был произведен в другой функции или скрипта заставят массив (стек) должны быть глубже. (ИМЯ_ФУНКЦИИ
специальный переменной массива Баш, он должен иметь непрерывный индексы, соответствующие > в стеке вызовов, пока это несбросить
.)
Так что вы можете добавить в начало скрипта:
function check()
{
if [[ ${FUNCNAME[-1]} != "source" ]] # bash 4.2+, use ${FUNCNAME[@]: -1} for older
then
printf "Usage: source %s\n" "$0"
exit 1
fi
}
check
При условии, что это просто бесполезно, а не вредные, чтобы выполнить скрипт, вы можете добавить
return 0 || printf 'Must be sourced, not executed\n' >&2
в конце сценария. возвращение
вне функции имеет ненулевой код возврата, если файл был произведен.
Когда вы исходный shell-скрипт, линии shebang игнорируется. Поставив в недопустимом притон, вы можете предупредить пользователя, что скрипт был ошибочно исполнен:
#!/bin/bash source-this-script
# ...
Сообщение об ошибке будет таким:
/bin/bash: source-this-script: No such file or directory
(Произвольное) имя аргумента уже дает сильный намек, но сообщение об ошибке все равно это'Т 100% понятно. Мы можем исправить это с помощью утилиты script источник этого сценария
, что находится где-то в свой "путь":
#!/bin/sh
echo >&2 "This script must be sourced, not executed${1:+: }${1:-!}"
exit 1
Теперь сообщение об ошибке будет таким:
This script must be sourced, not executed: path/to/script.sh
По сравнению с другими ответами, этот подход только требует минимальных изменений для каждого сценария (и имеет притон помогает при определение типа файла в редакторах и указывает оболочки диалект сценария, таким образом, есть даже преимущества). Недостатком является несколько непонятным сообщением об ошибке, или (один раз) добавлением другой скрипт.
Это не мешает явный вызов через Баш path/to/script.sh хотя (спасибо @Муру!).