Каталог Adding для СОЕДИНЕНИЯ КАНАЛОМ через Make-файл

Вы на самом деле натолкнулись на правильный термин ¹. Существует переменная среды SHLVL который все главные интерактивные оболочки (удар, tcsh, zsh) увеличивают 1, когда они запускают. Таким образом, если Вы запускаете оболочку в оболочке, SHLVL увеличения 1.

Это непосредственно не отвечает на Ваше беспокойство, однако, потому что SHLVL переносит вещи как эмуляторы терминала. Например, в моей типичной конфигурации, $SHLVL 2 в xterm, потому что уровень 1 соответствует оболочке, которая выполняет мои X сессий (~/.xinitrc или ~/.xsession).

То, что я делаю, должно отобразиться $SHLVL в моей подсказке, но только если родительский процесс оболочки является другой оболочкой (с эвристикой как, “если ее имя заканчивается в sh плюс дополнительная пунктуация и цифры, это - оболочка”). Тем путем у меня есть очевидный визуальный признак в редком случае оболочки, работающей под другой оболочкой.

Возможно, Вы предпочли бы обнаруживать оболочки, которые работают непосредственно под эмулятором терминала. Можно сделать это справедливо точно: это оболочки, родительский процесс которых имеет другой терминал управления, так, чтобы ps -o tty= -p$$ и ps -o tty= -p$PPID произведите другой вывод. Вы могли бы вручную сбросить SHLVL к 1 в этих оболочках или наборе Ваше собственное TERMSHLVL к 1 в этих оболочках (и увеличенный иначе).

¹, Хотя нельзя было бы думать это смотрящий на страницы руководства: ни одна из трех оболочек, которые поддерживают его, не включает слово “уровень” в их документацию SHLVL.

8
25.02.2014, 09:17
5 ответов

Вы просто не можете сделать этого. Нет никакого пути ¹, сделать процесс может изменить среду своего родителя (или его текущий каталог, о котором Вы могли бы думать затем).

На самом деле еще меньше - happending, чем Вы думаете.

  • Не все make реализации отражают присвоение на делание PATH переменная в среде; GNU делает (найденный на Linux, и другие системы) делает, но BSD делают, не делает.
  • Каждая командная строка под целью работает в отдельной подоболочке. (Кроме некоторого более старого BSD делают реализации.) Так export PATH строка работает на оболочке, которая завершается сразу впоследствии. Не то, чтобы эта строка сделала бы что-либо во-первых — если PATH определяется в той точке, это - потому что это уже находится в среде оболочки.

Сделайте для создания вещей автоматически. Если Вы хотите установить переменные для своей интерактивной среды, это не инструмент, на который необходимо смотреть. Вместо этого запишите отрывок оболочки и получите его в текущей оболочке:

. ./define-my-variables.sh

В Вашем make-файле получите сценарий в каждой подоболочке. Можно использовать обратную косую черту для создания долгой команды; помните это

  • Последовательность новой строки обратной косой черты разделяется, делают, таким образом, оболочка не будет видеть новой строки там.
  • Не забудьте снабжать префиксом каждую строку вкладкой, тем не менее.
  • Ошибочное поведение Make состоит в том, чтобы прерваться, если команда перестала работать. Оболочка не сделает этого по умолчанию, и отказ любой команды, но последнего останется незамеченным по умолчанию, таким образом, необходимо будет работать set -e.
install:
    set -e; \
    . ./define-my-variables.sh; \
    mkdir -p bin; \
    …

¹ Обязательное примечание: никакой нормальный путь. Даже удаленно вызов chdir через ptrace от отладчика не будет работать, как с большинством оболочек, потому что им не нравится изменять их текущий каталог под их ногами.

14
27.01.2020, 20:08
  • 1
    Er, я думаю, что "Вы просто не можете сделать, это" неправильно. См. ответ @Yeo: спасибо unix.stackexchange.com/a/291973/176350 –  XML 22.08.2017, 12:50
  • 2
    @XML делает что-то другое, что не является тем, что просит вопрос. –  Gilles 'SO- stop being evil' 22.08.2017, 19:21

Вы не можете. Это не возможно для подпроцесса (как make) изменить среду его родительского процесса.

Вы могли сделать что-то как

$ eval `make pathupdate`

Где pathupdate цель похожа:

pathupdate:
    @echo PATH=\"$(PATH)\"
7
27.01.2020, 20:08

Вы можете заставить Make рекурсивно вызывать себя с измененным окружением, как таковое:

dummy: build_all

all: 
    PATH=/new/directory:$(PATH) $(MAKE) build_all

build_all:
    your make rules 

Если вы хотите использовать фрагмент оболочки:

dummy: build_all

all:
    . ./define-my-variables.sh ; $(MAKE) build_all

build_all:
   your make rules
1
27.01.2020, 20:08

Ваш ответ можно найти здесь: https://stackoverflow.com/a/8942216/367461

По сути, вам следует сделать следующее:

export PATH := $(shell pwd)/bin:$(PATH)

test:
    mkdir -p ./bin
    @echo $(PATH)

Я тестировал это на Fedora 23 с GNU Make 4.0, и у меня он отлично работает.

6
27.01.2020, 20:08

Я собираюсь задать тот же вопрос, потому что мне не удалось заставить другой пример ответа работать.

Однако мне удалось найти рабочее решение с помощью команды eval . Я не совсем уверен, почему это не было опубликовано раньше.

do_something: 
    $(eval export PATH=$(shell pwd)/bin:$(PATH))
    @echo $(PATH)

Примечание: изменения ПУТЬ являются временными в самой программе make. После выхода из make PATH сбрасывается до более раннего значения.

2
27.01.2020, 20:08

Теги

Похожие вопросы