Я определяю сценарий оболочки, который пользователь должен source
выполнять, а не выполнять.
Есть ли обычный или интеллектуальный способ намека пользователю, что это так, например, с помощью расширения файла?
Есть ли код оболочки, который я могу написать в самом файле, который заставит его повторить сообщение и выйти, если он выполняется вместо источника, чтобы я мог помочь пользователю избежать этой очевидной ошибки?
x
, который просто содержит команду. your-script-to-be-sourced
, то все в порядке, но если он хочет выполнитьbash your-script-to-be-sourced
его, это должно быть запрещено? Какой смысл этого ограничения?env
переменных и оставляет их как вывод сценария де-факто . Новичок застрянет на несколько дней с загадкой, если вы позволите им исполниться.if __name__ == '__main__'
?Ответы:
Предполагая, что вы запускаете bash, поместите следующий код в начало скрипта, который вы хотите получить, но не выполняете:
В разделе bash
${BASH_SOURCE[0]}
будет содержаться имя текущего файла, который читает оболочка, независимо от того, был ли он получен или выполнен.Напротив,
$0
это имя текущего исполняемого файла.-ef
проверяет, являются ли эти два файла одним файлом Если они есть, мы предупреждаем пользователя и завершаем работу.Ни POSIX,
-ef
ниBASH_SOURCE
есть. Хотя-ef
поддерживается ksh, yash, zsh и Dash,BASH_SOURCE
требуется bash. Вzsh
, однако,${BASH_SOURCE[0]}
может быть заменено на${(%):-%N}
.источник
echo "Usage: source \"$myfile\""
source
не является портативным. Учитывая, что этот ответ зависит от bash, это не так уж плохо, но это хорошая привычка использовать портативный компьютер.
Неисполняемый файл может быть получен, но не выполнен, поэтому, в качестве первой линии защиты, хорошая подсказка не должна быть установкой флага ...
Edit: трюк, на который я только что наткнулся: сделать shebang любым исполняемым файлом, который не является интерпретатором оболочки,
/bin/false
заставляет скрипт возвращать ошибку (rc! = 0)источник
bash somefile.sh
...bash
(vd perl, python, awk ...), то вы посмотрели исходный код и увидели комментарий, в котором говорится, что не следует делать это :)somefile.pl
и Python какsomefile.py
, так что нет, я, вероятно, не читал комментарии (что это вообщеbash somefile.sh
такое ?) И корочеchmod +x somefile.sh; ./somefile.sh
bash
, сначала пытаютсяexecve
файл, но если это не удается, они проверяют файл вручную и вручную интерпретируют#!
и вызывают его через этот интерпретатор: это наследие со времен, когда#!
было чисто пользовательское пространство соглашение, а не обрабатывается самим ядром. Я думаюbash
, по крайней мере, не буду делать это для неисполняемых файлов, но я не знаю, переносимо ли ожидать такого нормального поведения от всех оболочек, из которых пользователь может вызывать скрипт.bash
которыеbash script.sh
могут быть опасными.В этом сообщении о переполнении стека предлагается несколько методов , из которых мне больше всего понравился метод на основе функций, предложенный Wirawan Purwanto и mr.spuratic :
Таким образом, вы можете добавить в начало сценария:
источник
Предполагая, что выполнение сценария просто бесполезно, а не вредно, вы можете добавить
до конца сценария.
return
снаружи функции имеет ненулевой код выхода, если файл не был получен.источник
return 2>/dev/null; echo "$0: This script must be sourced" 1>&2; exit 1
Когда вы создаете сценарий оболочки, строка shebang игнорируется. Вставив неверный shebang, вы можете предупредить пользователя о том, что скрипт был ошибочно выполнен:
Сообщение об ошибке будет таким:
(Произвольное) имя аргумента уже дает строгую подсказку, но сообщение об ошибке все еще не ясно на 100%. Мы можем исправить это с помощью служебного скрипта,
source-this-script
который находится где-то в вашемPATH
:Теперь сообщение об ошибке будет таким:
Сравнение с другими подходами
По сравнению с другими ответами этот подход требует лишь минимальных изменений в каждом сценарии (а наличие строки shebang помогает в обнаружении типа файла в редакторах и определяет диалект сценария оболочки, так что есть даже преимущества). Недостатком является несколько неясное сообщение об ошибке или (одноразовое) добавление другого сценария оболочки.
Это не мешает явному вызову через
bash path/to/script.sh
, хотя (спасибо @muru!).источник
bash some/script.sh
, что также проигнорирует Шебанг.#!/bin/echo 'You must source this script!'
или что-то в этом роде.