Как проверить возвращаемое значение из директивы оболочки
В моем Makefile мне нужно проверить, является ли текущий каталог SVN-репо или нет, и если я не хочу указывать ошибку с помощью директивы $(error) в Makefile.
Итак, я планирую использовать возвращаемое значение $(shell svn info.), но я не уверен, как получить это значение из Makefile.
Примечание. Я не пытаюсь получить возвращаемое значение в рецепте, а скорее в середине файла Makefile.
Сейчас я делаю что-то вроде этого, которое работает только потому, что stdout пуст, когда это ошибка:
SVN_INFO := $(shell svn info . 2> /dev/null)
ifeq ($(SVN_INFO),)
$(error "Not an SVN repo...")
endif
Мне все равно хотелось бы узнать, возможно ли получить возвращаемое значение в Makefile.
Ответы
Ответ 1
Это сработало для меня - на основе ответа @eriktous, с незначительной модификацией перенаправления stdout, а также для пропуска вывода из информации svn о действительном svn-репо.
SVN_INFO := $(shell svn info . 1>&2 2> /dev/null; echo $$?)
ifneq ($(SVN_INFO),0)
$(error "Not an SVN repo...")
endif
Ответ 2
Как использовать $?
для эхо-вывода статуса выхода последней команды?
SVN_INFO := $(shell svn info . 2> /dev/null; echo $$?)
ifeq ($(SVN_INFO),1)
$(error "Not an SVN repo...")
endif
Ответ 3
Может быть, что-то вроде этого?
IS_SVN_CHECKED_OUT := $(shell svn info . 1>/dev/null 2>&1 && echo "yes" || echo "no")
ifne ($(IS_SVN_CHECKED_OUT),yes)
$(error "The current directory must be checked out from SVN.")
endif
Ответ 4
Если вы хотите сохранить исходный вывод, вам нужно сделать некоторые трюки. Если вам повезло, что GNU Make 4.2 (выпущен в 2016-05-22) или позже в вашем распоряжении, вы можете использовать переменную .SHELLSTATUS
следующим образом.
var := $(shell echo "blabla" ; false)
ifneq ($(.SHELLSTATUS),0)
$(error shell command failed! output was $(var))
endif
all:
@echo Never reached but output would have been $(var)
В качестве альтернативы вы можете использовать временный файл или играть с Make eval
, чтобы сохранить строку и/или код выхода в переменную Make. В приведенном ниже примере делается это, но я бы хотел увидеть лучшую реализацию, чем эта неловко сложная версия.
ret := $(shell echo "blabla"; false; echo " $$?")
rc := $(lastword $(ret))
# Remove the last word by calculating <word count - 1> and
# using it as the second parameter of wordlist.
string:=$(wordlist 1,$(shell echo $$(($(words $(ret))-1))),$(ret))
ifneq ($(rc),0)
$(error shell command failed with $(rc)! output was "$(string)")
endif
all:
@echo Never reached but output would have been \"$(string)\"