Не припиняйте робити процес, якщо команда не працює, але перевірте стан виходу


22

Я намагаюся доручити GNU Make 3.81 не зупинятися, якщо команда не спрацьовує (тому я вказую префікс команди -), але я також хочу перевірити стан виходу в наступній команді та надрукувати більш інформативне повідомлення. Однак мій Makefile нижче не вдається:

$ cat Makefile 
all:
    -/bin/false
    ([ $$? -eq 0 ] && echo "success!") || echo "failure!"
$
$ make
/bin/false
make: [all] Error 1 (ignored)
([ $? -eq 0 ] && echo "success!") || echo "failure!"
success!

Чому Makefile вище перегукується з "успіхом!" замість "провал!" ?

оновлення:

Слідуючи та розширюючи прийняту відповідь, нижче - як слід писати:

failure:                                                                                                                                                                                                                                      
    @-/bin/false && ([ $$? -eq 0 ] && echo "success!") || echo "failure!"                                                                                                                                                                 
success:                                                                                                                                                                                                                                      
    @-/bin/true && ([ $$? -eq 0 ] && echo "success!") || echo "failure!"     

2
Ви можете вивчити .ONESHELL:директиву.
Джонатан Леффлер

.ONESHELL запустить весь блок прийому в одній оболонці, що має ефект: якщо перша команда не вдасться, наступна буде виконана без проблем. Для запобігання цього .SHELLFLAGS = -ecслід використовувати. Але в цьому випадку ви більше не можете використовувати -префікс (для особистої команди квитанції), тому що make запише, що помилка ігнорується, але все-таки вийде з ладу весь блок. Отже, || :це одне рішення для ігнорування команди. Але це не крос-платформа (у Windows немає || :чи || true)
Paul-AG

Відповіді:


14

Кожна команда оновлення в правилі Makefile виконується в окремій оболонці. Так $? не містить статусу виходу попередньої невдалої команди, вона містить будь-яке значення за замовчуванням для $? в новій оболонці. Ось чому ваш [$? -eq 0] тест завжди вдається.


10

Тест вам не потрібен, $?оскільки &&працює, якщо $?дорівнює нулю, і ||продовжується у випадку ненульового значення повернення.

І мінус вам не потрібен, оскільки значення повернення, яке потрібно зробити, взято з останнього програмного виклику програми. Тож це чудово працює

збій:

      @/bin/false && echo "success!" || echo "failure!" 

успіх:

      @/bin/true && echo "success!" || echo "failure!"

Відбувається протилежне: Якщо ви хочете зробити власне повідомлення і хочете все-таки порушити процес створення з ненульовим значенням, вам потрібно написати щось подібне:

збій:

      @/bin/false && echo "success!" || { echo "failure!"; exit 1; }

8

З ГНУ складіть документацію :

Коли помилки слід ігнорувати, через прапор '-' або '-i', зроблять трактування повернення помилки так само, як і успіх , за винятком того, що він виводить повідомлення, яке повідомляє вам код статусу, з якого вийшла оболонка, і каже, що помилка була проігнорована.

Щоб використовувати makeстатус виходу у подібному випадку, виконайте makeз сценарію:

#!/bin/bash
make
([ $? -eq 0 ] && echo "success!") || echo "failure!"

І ваш Makefile містить:

all:
    /bin/false
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.