Сделайте по ошибке думает правило, за которым следуют из-за файла 0 размеров, сгенерированного выходным перенаправлением

Другой (для меня) полезные команды являются J, K, который работает j, k, но не прекращайте прокручивать при начинании или конце файла: это полезно, потому что я часто использую терминальную границу в качестве визуального маркера.

Как примечание, они, кажется, не документированы, afaik.

Затем, я использую меньше для передачи по каналу вместе заархивированный и не заархивированный файл (он работает благодаря lesspipe), как в less /var/log/dpkg.log* | less

5
06.07.2011, 20:12
4 ответа

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

.DELETE_ON_ERROR:

Затем Вы получаете следующее:

$ cat Makefile
.DELETE_ON_ERROR:
foo:
    false > foo

$ make
false > foo
make: *** [foo] Error 1
make: *** Deleting file `foo'
zsh: exit 2     make

$ stat foo
stat: cannot stat `foo': No such file or directory

От ошибок в рецептах:

Обычно, когда строка рецепта перестала работать, если она изменила конечный файл вообще, файл повреждается и не может использоваться — или по крайней мере она не полностью обновляется. Все же метка времени файла говорит, что это теперь актуально, таким образом, в следующий раз make выполнения, это не попытается обновить тот файл. Ситуация состоит все равно в том как тогда, когда оболочка уничтожается сигналом; посмотрите Прерывания. Таким образом, обычно правильный поступок должен удалить конечный файл если сбои рецепта с начала изменить файл. make сделает это если .DELETE_ON_ERROR появляется как цель. Это почти всегда, что Вы хотите make чтобы сделать, но это не историческая практика; таким образом для совместимости, необходимо явно запросить это.

11
27.01.2020, 20:31
  • 1
    Преимущество .DELETE_ON_ERROR это, это автоматически относится к каждому правилу. Это имеет оборотные стороны хотя: это характерно для GNU, делают; это не инициировало, если сборка прервана яростно (сбой питания, немаскируемый сигнал); это удаляет частичный файл, который может быть полезным в исследовании неудавшихся сборок. –  Gilles 'SO- stop being evil' 06.07.2011, 21:58

Так как это кажется этим foo.sh что-то, что Вы записали (или сгенерирован чем-то, что Вы записали), я рассмотрю добавление a -o отметьте к нему, который берет имя выходного файла. Затем Вы не должны зависеть от поведения перенаправления ввода-вывода по умолчанию. Ваш сценарий может очистить частичные выходные файлы или возможно даже постараться не создавать файл во-первых, если можно обнаружить ошибку достаточно рано.

2
27.01.2020, 20:31

Каждый раз, когда возможно, правила make-файла должны сначала создать свою цель под временным именем, затем переместить его в место. Тем путем, если процесс сборки прерван по какой-либо причине, не будет полузаписанный конечный файл, который нельзя отличить из полностью записанного файла.

out.txt: foo.sh input.txt
        ./foo.sh -i input.txt >$@.tmp
        mv -f $@.tmp $@

mv -f $@.tmp $@ общая идиома make-файла.

Ответ Juliano показывает вариант, где название временного файла сгенерировано динамично. Динамическое поколение имени требуется, если может быть больше чем один процесс, генерирующий ту же цель или если каталог может быть записан в другими пользователями. Это очень редко имеет место для дерева сборки (если бы они были проблемами, большим количеством из того, что продолжается в типичном make-файле, то повредился бы), таким образом, дополнительная сложность обычно не необходима.

7
27.01.2020, 20:31
  • 1
    Это на самом деле необходимо? Я думал, делают, очистил бы полузаписанные файлы, если бы это было прервано, или процесс имеет сигнал (и экспериментирование, кажется, указывает, что делает). По умолчанию это не очищает файлы, если ненулевые выходы процесса, но это что .DELETE_ON_ERROR находится в моем ответе; с этим на не должно быть никакой потребности в этом временном –  Michael Mrozek♦ 06.07.2011, 20:58
  • 2
    @Michael манипулирования файла Что если make умирает, не имея времени для чистки (сбой питания, OOM, пользователь, отправляющий a KILL сигнал, …)? –  Gilles 'SO- stop being evil' 06.07.2011, 21:09
  • 3
    Ну, как часто это происходит? Если Вы kill -9луг make Вы заслуживаете того, что Вы получаете, и я надеялся бы, что кто-то собирается сделать чистую сборку, если существует что-то исключительное как Примечание сбоя питания –  Michael Mrozek♦ 06.07.2011, 21:32

Я предполагаю это foo.sh правильно возвраты, ненулевые на ошибке. Затем необходимо сделать временный файл, и только перезаписать вывод на успехе.

tmp=$$(mktemp) && ./foo.sh input.txt > $$tmp && mv $$tmp $@ || rm -f $$tmp && false
1
27.01.2020, 20:31
  • 1
    я не удалил бы $tmp если поколение перестало работать, частичные файлы могут быть полезными для отладки отказавших сборок. Если Вы делаете, необходимо удостовериться сбои команды если rm вызывается, например. || rm $$tmp && false. –  Gilles 'SO- stop being evil' 06.07.2011, 20:54
  • 2
    Да, это - хорошая идея иметь в наличии частичные файлы для отладки, но это усложнило бы решение немного. Я добавил бит о лжи, хорошей. –  Juliano 06.07.2011, 21:12

Теги

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