Экспорт переменных среды из дочернего bash-скрипта в GNU Make - PullRequest
0 голосов
/ 08 октября 2019

У меня есть скрипт "set_env.py", который выводит следующее выполнение uppon:

export MY_VAR_1=some_value
export MY_VAR_2=some_other_value

Я не могу изменить этот скрипт, он предоставляется в моей текущей среде.

Далее яу меня есть Makefile, который выглядит следующим образом:

SHELL := /bin/bash

all: set_env
    env | grep MY_VAR    

set_env:
    eval ./set_env.py

С этим make-файлом я ожидал, что grep перечислит две мои переменные, однако кажется, что среда не установлена.

Я подозреваю, что это потому, чтоmake создает подпространство для каждой строки, поэтому переменные, заданные в первой строке, не будут доступны во второй.

Итак, вопрос в том, как мне поступить при экспорте среды изнеприкосновенный скрипт в моем makefile ?

Ответы [ 2 ]

2 голосов
/ 08 октября 2019

На самом деле вывод питона действителен make . Один из вариантов заключается в том, чтобы прочитать вывод питона непосредственно в make-файл. Единственная ложка дегтя состоит в том, что $(shell) не разрезает горчицу.

include Environment.mk

PHONY: test
test:
    env | grep MY_VAR

Environment.mk:
    ./set_env.py >$@-tmp
    mv $@-tmp $@

Как это работает? Первое, что пытается сделать make , - это убедиться, что сам make-файл обновлен. Так как мы указали включить Environment.mk, make должен также быть актуальным.

  • Make находит правило для Environment.mk
  • Питон запускается, создается Environment.mk
  • Environment.mk, создается две make переменные с атрибутом экспорта
  • Makefile теперь обновлен, поэтому make переходит к цели (в нашем случае test)
  • Make запускает testрецепт, экспорт любых переменных с атрибутом экспорта.

Нет рекурсии, но вы должны убедиться, что питон всегда выплевывает make совместимый синтаксис.

EDIT

Как отмечает @raspy, это еще не все. В существующем состоянии после создания Environment.mk он никогда не будет регенерирован.

Если set_env.py генерирует другой вывод, вы должны сообщить make , что это за условия, добавив зависимости.

Если для запуска set_env.py требуется тривиальное время, я советую простой .PHONY. Таким образом, он будет работать каждый раз, когда вы запускаете make , и Environment.mk никогда не устареет.

.PHONY: Environment.mk
0 голосов
/ 08 октября 2019

Рекурсивный make - твой друг, я боюсь.

.PHONY: all
all:
    eval $$(./set_env.py) && ${MAKE} test

.PHONY: test
test:
    env | grep MY_VAR    

Здесь есть несколько движущихся частей.

  • make all выполняет команду оболочки eval $(./set_env.py) && make test
  • Оболочка сначала выполняет подстановку команд
    • $(./set_env.py) заменяется командами экспорта
  • Команды экспорта передаются в (оболочку) eval команда
    • Переменные среды определены, , но только для этого вызова оболочки
  • eval завершается успешно, поэтому выполнение переходит ккоманда после &&
  • Make выполняется рекурсивно, но эта вторая make имеет расширенную среду
...