Вопрос или проблема
используйте grep внутри make, чтобы проверить, содержит ли файл экспорт в PATH
Мне нужна функция make
, которая проверяет, экспортирован ли указанный путь в моем файле .bashrc
/.zshrc
/и т. д.
Поскольку нужно экранировать символы два или три раза (shell + make + regex), я застрял. Моя текущая попытка:
define ensure_in_path
@rg='export\s+PATH\s*=\s*\"\\$$PATH:${1}\"'; \
if ! cat "${1}" | /bin/grep -q -E $$rg ; then \
echo "добавлено \"${2}\" в exports в \"${1}\".";\
fi
endef
Что бы я хотел – это совпадение с чем-то вроде export\s+=\s*\"?\$PATH:<путь здесь>\"
. (Это вообще хорошее совпадение?)
Пример:
$(call ensure_in_path,$$HOME/.bashrc,$$HOME/.local/bin)
должен проверить, есть ли export PATH="$PATH:/home/<имя пользователя>/.local/bin"
в /home/<имя пользователя>/.bashrc
, и если нет, добавить его туда.
Конечно, было бы хорошо также расширить пути внутри .bashrc
перед их проверкой, но это вопрос на другой день.
Редактирование 1:
Работающая версия bash:
pth="$HOME/.local/bin"
rg="export\s+PATH\s*=\s*\"?\\\$PATH:${pth}\"?"
cat $HOME/.bashrc | grep -qE $rg
Все еще неработающая версия make:
define ensure_in_path
@rg="export\s+PATH\s*=\s\"?\\\\$$PATH:${2}\"?"; \
echo $$rg;\
if cat "${1}" | /bin/grep -qE $$rg ; then \
echo "путь добавлен..."; \
fi
endef
Это неверно экранирует $PATH.
Ответ или решение
Для решения вашей задачи, нам нужно создать функцию в Makefile, которая бы проверяла, содержится ли указанный путь в переменной PATH
, экспортируемой в файле конфигурации, таком как .bashrc
или .zshrc
. Мы будем использовать grep
для выполнения этой проверки.
Вот корректный способ реализации вашей функции ensure_in_path
, чтобы она работала должным образом:
define ensure_in_path
@rg="export\\s\\+PATH=\\\"?\\$$PATH:${2}\\\"?"; \
echo "Проверка наличия пути в файле ${1}..."; \
if ! grep -qE $$rg "${1}"; then \
echo "Добавление \"${2}\" в \"${1}\"."; \
echo "export PATH=\"$$PATH:${2}\"" >> "${1}"; \
else \
echo "Путь \"${2}\" уже экспортирован в \"${1}\"."; \
fi
endef
Объяснение кода:
-
Регулярное выражение (
rg
):export\\s\\+PATH=
: соответствует строке, начинающейся сexport
, после которой идет один или более пробелов, и затемPATH=
.\\\"?
: проверяет, опционально ли присутствует открывающая кавычка.\\$$PATH:${2}
: здесь мы включаем указанный путь${2}
, добавляя его к переменнойPATH
, а перед$PATH
необходимо экранировать$
, чтобы Make не интерпретировал его.\\\"?
: аналогично, проверяет, опционально ли присутствует закрывающая кавычка.
- Команды в условии:
grep -qE $$rg "${1}"
: проверяет, существует ли строка, соответствующая регулярному выражению$$rg
, в файле${1}
. Если строка не найдена, выполняется добавление.- Если условие ложно (путь не найден), мы добавляем новый путь к
PATH
в конец файла${1}
с помощью конструкцииecho "export PATH=\"$$PATH:${2}\"" >> "${1}"
. - Если же путь уже существует, выводится сообщение об этом.
Пример вызова:
$(call ensure_in_path,$$HOME/.bashrc,$$HOME/.local/bin)
Этот вызов проверит, содержит ли файл ~/.bashrc
строку с экспортом пути, и добавит указанный путь, если его нет.
Уточнения:
- Обратите внимание, что этот метод не обрабатывает случаи, когда путь может уже находиться в другом формате (например, без кавычек или с дополнительными пробелами). Вы можете уточнить регулярное выражение для обработки этих ситуаций, если это необходимо.
- Если вам нужно обрабатывать другие конфигурационные файлы, просто измените аргумент
${1}
на нужный файл.