Ответ 1
Здесь возможно решение, не требующее bash. Представьте, что у вас есть две программы thisworks
и thisfails
, которые не работают или работают нормально, соответственно. Тогда вы оставите только work.gz
, удалив fail.gz
, т.е. создать gzipped make target, если и только если программа выполнена правильно:
all: fail.gz work.gz
work.gz:
( thisworks && touch [email protected] ) | gzip -c -9 >[email protected]
rm [email protected] || rm [email protected]
fail.gz:
( thisfails && touch [email protected] ) | gzip -c -9 >[email protected]
rm [email protected] || rm [email protected]
Пояснение:
В первой строке правила work.gz
thisworks
будет успешно завершен, и будет создан файл work.gz.ok
, и все stdout перейдут через gzip в work.gz
. Затем во второй строке, поскольку work.gz.ok
существует, первая команда rm
также успешно завершается - и поскольку ||
короткое замыкание, второй rm
не запускается и поэтому work.gz
не удаляется.
OTOH, в первой строке правила fail.gz
thisfails
выйдет с ошибкой, а fail.gz.ok
не будет создан. Все stdout все еще проходит через gzip в fail.gz
. Затем во второй строке, поскольку fail.gz.ok
не существует, первая команда rm
завершается с ошибкой, поэтому ||
пытается выполнить вторую команду rm
, которая удаляет файл fail.gz
.
Чтобы легко проверить, что это работает так, как нужно, просто замените thisworks
и thisfails
командами true
и false
, соответственно, поместите их в Makefile и введите make
.
(Благодаря добрым людям в #autotools, которые помогают мне в этом.)