В больших bash-проектах часто есть несколько вспомогательных файлов (.sh или .bash), которые содержат функции и настройки. Проблема в том, что:
📍Скрипт может запуститься в другом каталоге - пути сломаются
📍Некоторые модули могут отсутствовать или лежать в нестандартных местах
📍При изменении структуры проекта придётся вручную переписывать source
Решение: динамическое подключение модулей
1️⃣ Автоматический source по списку зависимостей
#!/bin/bash
set -e
# Список модулей, которые нужны для работы
modules=("logger.sh" "utils.sh" "net.sh")
# Каталоги для поиска
search_paths=(
"$PWD/lib"
"$PWD/modules"
"/usr/local/share/myscript"
)
for mod in "${modules[@]}"; do
found=0
for path in "${search_paths[@]}"; do
if [[ -f "$path/$mod" ]]; then
source "$path/$mod"
echo "[OK] Loaded $mod from $path"
found=1
break
fi
done
if (( !found )); then
echo "[ERROR] Module $mod not found" >&2
exit 1
fi
done
Такой подход позволяет легко добавлять новые пути в поиск - модуль подтянется сам.
2️⃣ Dynamic sourcing по зависимостям из конфигурации. Можно вынести список зависимостей в отдельный файл deps.txt:
logger.sh
utils.sh
net.sh
А в скрипте:
while IFS= read -r dep; do
found=0
for path in "${search_paths[@]}"; do
if [[ -f "$path/$dep" ]]; then
source "$path/$dep"
found=1
break
fi
done
(( found )) || { echo "[MISSING] $dep" >&2; exit 1; }
done < deps.txt
3️⃣ Поиск относительно текущего скрипта. Чтобы скрипт работал из любого места:
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/lib/logger.sh"
▪️ Плюсы подхода:
✅Нет жестких путей;
✅Можно запускать в разных окружениях;
✅Удобно для open-source проектов и shared-библиотек;
✅Легко расширять - просто добавь файл в deps.txt.
BashTex 📱 #bash