Как получить статус выхода команды оболочки, используемой в GNU Makefile?
У меня есть правило make файла, пока я выполняю инструмент Linux. Мне нужно проверить состояние завершения команды инструмента, и если эта команда не удалась, make должен быть прерван.
Я пытался проверить с помощью $?, $$?\$? и т.д. в make файле. Но они дают мне синтаксическую ошибку при запуске makefile.
Как правильно это сделать?
Вот соответствующее правило в Makefile
mycommand \
if [ $$? -ne 0 ]; \
then \
echo "mycommand failed"; \
false; \
fi
Ответы
Ответ 1
В файле makefile -:
mycommand || (echo "mycommand failed $$?"; exit 1)
Каждая строка в действии makefile вызывает новую оболочку - ошибка должна быть проверена в строке действия, где команда не удалась.
Если mycommand завершает работу, логические ветки к выражению echo затем завершаются.
Ответ 2
Вот несколько других подходов:
some_recipe:
@echo $(shell echo 'doing stuff'; exit 123)
@echo 'command exited with $(.SHELLSTATUS)'
@exit $(.SHELLSTATUS)
Выход:
$ make some_recipe
doing stuff
command exited with 123
make: *** [Makefile:4: some_recipe] Error 123
У него есть предостережение о том, что выходные данные команды shell
не передаются в потоковом режиме, поэтому вы просто получите дамп stdout после его завершения.
some_recipe:
@echo 'doing stuff'; exit 123;\
EXIT_CODE=$$?;\
echo "command exited with $$EXIT_CODE";\
exit $$EXIT_CODE
Выход:
$ make some_recipe
doing stuff
command exited with 123
make: *** [Makefile:2: some_recipe] Error 123
Это по сути одна строка команд оболочки, разделенных точкой с запятой.
Исключать любые новые строки, которые вы хотите, раздражает, и легко забыть точки с запятой, но я использовал этот подход исключительно из-за оговорки, упомянутой выше.
Ответ 3
Если вы хотите, чтобы make
был прерван, если инструмент выходит с ненулевым статусом, make
уже сделает это по умолчанию.
Пример Makefile
:
a: b
@echo making [email protected]
b:
@echo making [email protected]
@false
@echo already failed
.
Это то, что происходит с моим make
:
$ make
making b
make: *** [Makefile:6: b] Error 1
Убедитесь, что частично или полностью созданные цели удалены в случае неудачи.
Например, этот
a: b
@gena $+ > [email protected]
b:
@genb > [email protected]
неверно: если при первой попытке genb
не удастся, он, вероятно, оставит неправильный b
, который при второй попытке make
будет считать правильным. Поэтому вам нужно сделать что-то вроде
a: b
@gena $+ > [email protected] || { rm [email protected]; exit 1; }
b:
@genb > [email protected]