Как определить скрипт для быть получены не запустить

Я определяю сценарий оболочки, который пользователь должен источник, а не казнить.

Есть обычный или интеллектуальный способ намекнуть пользователю, что это тот случай, например, через расширение?

Есть код оболочки я могу писать в сам файл, что приведет к его эхо-сообщение и выход, если он выполняется вместо источников, так что я могу избежать этой очевидной ошибки?

Комментарии к вопросу (3)
Решение

Предполагая, что вы используете Баш, поместите следующий код в начале скрипта, который вы хотите быть получены, но не исполнены:

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]} можно заменить ${(%):-%Н}.

Комментарии (2)

Файл не является исполняемым, могут быть получены, но не исполнены, поэтому, в качестве первой линии обороны, не установив исполняемый флаг должен быть хороший намек...

Редактировать: я просто наткнулся на: сделайте такое быть любой исполняемый файл, что это'т интерпретатор командной строки, /Бен/значение false делает скрипт возвращает ошибку (ГС!=0)

#!/bin/false "This script should be sourced in a shell, not executed directly"
Комментарии (5)

Существует несколько методов, предложенных в этот переполнение стека пост, из которых, мне понравилась функция на основе предложенного 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
Комментарии (0)

При условии, что это просто бесполезно, а не вредные, чтобы выполнить скрипт, вы можете добавить

return 0 || printf 'Must be sourced, not executed\n' >&2

в конце сценария. возвращение вне функции имеет ненулевой код возврата, если файл был произведен.

Комментарии (1)

Когда вы исходный 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 хотя (спасибо @Муру!).

Комментарии (3)