У меня есть следующая структура директорий: ``` ~/AAA ~/AAA/bash ~/AAA/site ~/BBB ~/BBB/bash ~/BBB/site ~/NNN ~/NNN/bash ~/NNN/site ``` Внутри директории `bash/` всегда находятся файлы с расширением `.sh`. Обычно я работаю в директории `site/`. Я создал файл с алиасами `~/.bash_aliases`, где указал следующее: ```bash alias get1="bash ../bash/111.sh" alias get2="bash ../bash/222.sh" alias getN="bash ../bash/NNN.sh" ``` **Первая проблема.** В каждом скрипте есть файл с переменными, который я подключаю с помощью: ```bash . ./variables.sh ``` Однако, когда я запускаю алиас, например, `get1`, я получаю сообщение об ошибке: `variables.sh: No such file or directory`. Я понимаю, что можно использовать абсолютный путь, но возможно ли сделать код универсальным, чтобы не прописывать абсолютный путь в каждом файле? **Второй вопрос.** Возможно ли настроить алиас так, чтобы он правильно работал, независимо от того, в какой поддиректории корневой директории я нахожусь, например, в `~/BBB` или `~/BBB/bash`? Хочу, чтобы, находясь внутри `~/BBB`, я мог запускать скрипты из `~/BBB/bash/` независимо от уровня вложенности. Кроме того, если бы я скопировал директорию `bash/` в новую директорию `~/CCC/`, я хотел бы, чтобы скрипты продолжали работать без изменений. Если это возможно, что мне нужно сделать и что искать?
Для решения ваших задач в bash, вам нужно использовать относительные пути и знать местоположение скрипта, который вы запускаете. Это можно сделать с помощью переменной `$BASH_SOURCE` и встроенной команды `dirname`. Вот как можно организовать решение по двум вашим вопросам:
### 1. Решение проблемы с подключением файла `variables.sh`
Когда вы запускаете скрипт через алиас, текущая директория остается той, где вы запускали команду, а не тем местом, где находится файл скрипта. Чтобы подключить `variables.sh` корректно, нужно использовать `dirname` для получения пути к вашему скрипту и затем разделить его на части:
Вместо:
```bash
. ./variables.sh
```
Используйте:
```bash
. "$(dirname "${BASH_SOURCE[0]}")/variables.sh"
```
Это гарантирует, что путь к `variables.sh` будет корректным независимо от того, где запущен ваш aliass.
### 2. Сделать алиасы универсальными
Теперь вам нужно настроить ваши алиасы так, чтобы они правильно работали, независимо от текущей директории. Вы можете создать функцию в вашем `.bash_aliases`, которая будет запускать скрипт `111.sh`, `222.sh` и `NNN.sh` из директории `bash`, находясь в любой поддиректории.
Вот пример, как это можно сделать:
```bash
get_script() {
local script_name="$1"
local script_path="$(dirname "$(realpath "$0")")/../bash/${script_name}.sh"
bash "$script_path"
}
alias get1='get_script 111'
alias get2='get_script 222'
alias getN='get_script NNN'
```
В этом примере функция `get_script` получает имя скрипта, формирует путь к нему и запускает его. Строка `realpath "$0"` возвращает абсолютный путь к текущей директории, где находится скрипт, что позволяет сгенерировать корректный путь к скрипту в `bash`.
### 3. Как это работает в разных директориях
Этот подход работает независимо от того, где вы находитесь, потому что `realpath` обеспечит корректное определение пути относительно директории, где был вызван скрипт. Таким образом, если вы скопируете папку `bash` в другую директорию, скрипты будут продолжать работать, так как путь формируется динамически.
### Заключение
Таким образом, вы можете легко управлять путями к вашим скриптам и использовать алиасы, которые будут работать в любой директории без необходимости прописывать абсолютные пути.
Внутри каждого скрипта есть файл с переменными.Сменяйте рабочий каталог на тот, из которого запускается скрипт.
Я подключаю его так:
. ./variables.sh
Но при запуске алиаса, например get1, я получаю сообщение об ошибке: variables.sh: No such file or directory.
cd $(dirname $(realpath $0)) ./variables.sh
А нельзя ли сделать путь внутри алиаса таким, чтобы находясь в любой поддириктории корневой директории, например в ~/BBB, или в ~/BBB/bash, алиас срабатывал верно?В алиасе пропишите абсолютный путь. Скрипты будут универсальные, алиасы не универсальные.
Либо напишите один скрипт, который будет запускать любые по параметру:
вместо get1 будете вызывать get 1
а внутри
т.е. по get 123 будет запущено ~/123/bash/123.sh[ -d ~/$1/bash ] || (echo "нет каталога"; exit 1) [ -f ~/$1/bash/$1.sh ] || (echo "нет скрипта"; exit 2) echo "запускаю" ~/$1/bash/$1.sh