В моем сценарии bash используется множество проверок, например:
if [ something bad ] ; then
echo "error message"
exit 1
fi
Я обнаружил, что если пользователь выполняет его через source my-script.sh, а не через ./my-script.sh, этот exit 1закрывает оболочку пользователя!
И пользователь не видит сообщения об ошибке!
Как мне узнать, что это сценарий source-d, и как мне выйти (с ненулевым кодом статуса) из сценария source-d? В общем, что с этим делать?





Кажется, здесь может быть 2 части. Во-первых, нужно знать, когда вы выполняете сценарий sourced, а не выполняемый. Это можно найти в ответе это, а для bash они предлагают:
[[ "$0" != "$BASH_SOURCE" ]] && sourced=1 || sourced=0
чтобы сказать, есть ли у вас источник.
Если у вас есть источник, вы захотите использовать return вместо exit.
Вы можете сохранить эту функцию в переменной с чем-то вроде
if [[ $sourced -eq 1 ]]; then
ret=return
else
ret=exit
fi
а затем, когда вы захотите использовать подходящий, вы просто воспользуетесь
$ret 1
Для тех, кто предпочитает if:
# find out how the script was invoked
# we don't want to end the user's terminal session!
if [[ "$0" != "$BASH_SOURCE" ]] ; then
# this script is executed via `source`!
# An `exit` will close the user's console!
EXIT=return
else
# this script is not `source`-d, it's safe to exit via `exit`
EXIT=exit
fi
а потом
$EXIT 1
Не используйте заглавные буквы для частных переменных вашего скрипта. Все заглавные буквы зарезервированы для системных переменных.
Определять:
[[ "$0" == "$BASH_SOURCE" ]] && ret=exit || ret=return
Использовать:
$ret 1
Можно задокументировать, должен ли ваш скрипт быть создан или выполняться, и ожидать, что пользователь будет следовать этому требованию.