Как проверить, существует ли файл в Makefile, чтобы я мог удалить его? - PullRequest
117 голосов
/ 05 апреля 2011

В чистом разделе моего Makefile я пытаюсь проверить, существует ли файл, перед окончательным удалением. Я использую этот код, но получаю ошибки.

Что с ним не так?

 if [ -a myApp ]
 then
     rm myApp
 fi

Я получаю это сообщение об ошибке

 if [ -a myApp ]
 /bin/sh: Syntax error: end of file unexpected (expecting "then")
 make: *** [clean] Error 2

Ответы [ 10 ]

189 голосов
/ 13 декабря 2013

Странно видеть так много людей, использующих сценарии оболочки для этого. Я искал способ использовать собственный синтаксис makefile, потому что я пишу это вне какой-либо цели. Вы можете использовать функцию wildcard, чтобы проверить, существует ли файл:

 ifeq ($(UNAME),Darwin)
     SHELL := /opt/local/bin/bash
     OS_X  := true
 else ifneq (,$(wildcard /etc/redhat-release))
     OS_RHEL := true
 else
     OS_DEB  := true
     SHELL := /bin/bash
 endif 

Обновление:

Я нашел способ, который действительно работает для меня:

ifneq ("$(wildcard $(PATH_TO_FILE))","")
    FILE_EXISTS = 1
else
    FILE_EXISTS = 0
endif
47 голосов
/ 05 апреля 2011

Для продолжения может потребоваться обратная косая черта в конце строки (хотя, возможно, это зависит от версии make):

if [ -a myApp ] ; \
then \
     rm myApp ; \
fi;
42 голосов
/ 08 сентября 2015

Проблема в том, что вы разделяете команду на несколько строк.Таким образом, вы можете использовать \ в конце строки для продолжения, как описано выше, или вы можете получить все на одной строке с оператором && в bash.

Затем вы можете использовать команду test, чтобы проверить, существует ли файл, например:

test -f myApp && echo File does exist

-f file Истина, если файл существует и является обычным файлом.

-s file Истина, если файл существует и имеет размер больше нуля.

или нет:

test -f myApp || echo File does not exist
test ! -f myApp && echo File does not exist

test эквивалентно[ команда.

[ -f myApp ] && rm myApp   # remove myApp if it exists

, и он будет работать, как в исходном примере.

См. help [ или help test для дальнейшего синтаксиса.

26 голосов
/ 14 февраля 2013

Или просто поместите его в одну строку, как make нравится:

if [ -a myApp ]; then rm myApp; fi;
19 голосов
/ 15 декабря 2017

Во втором верхнем ответе упоминается ifeq, однако в нем не упоминается, что они должны находиться на том же уровне, что и имя цели, например, для загрузки файла, только если он в данный момент не существует, следующее код может быть использован:

if fi
download:
ifeq (,$(wildcard ./glob.c))
    curl … -o glob.c
endif
12 голосов
/ 05 апреля 2011

Отсутствует точка с запятой

if [ -a myApp ];
then
  rm myApp
fi

Однако я предполагаю, что вы проверяете существование перед удалением, чтобы предотвратить появление сообщения об ошибке.Если это так, вы можете просто использовать rm -f myApp, который «принудительно» удаляет, то есть не выдает ошибку, если файл не существует.

11 голосов
/ 25 ноября 2016
FILE1 = /usr/bin/perl
FILE2 = /nofile

ifeq ($(shell test -e $(FILE1) && echo -n yes),yes)
    RESULT1=$(FILE1) exists.
else
    RESULT1=$(FILE1) does not exist.
endif

ifeq ($(shell test -e $(FILE2) && echo -n yes),yes)
    RESULT2=$(FILE2) exists.
else
    RESULT2=$(FILE2) does not exist.
endif

all:
    @echo $(RESULT1)
    @echo $(RESULT2)

Результаты выполнения:

bash> make
/usr/bin/perl exists.
/nofile does not exist.
5 голосов
/ 29 августа 2016

Решение одной строки:

   [ -f ./myfile ] && echo exists

Решение одной строки с ошибкой:

   [ -f ./myfile ] && echo exists || echo not exists

Пример, используемый в моих директивах make clean:

clean:
    @[ -f ./myfile ] && rm myfile || true

И make clean всегда работает без каких-либо сообщений об ошибках!

0 голосов
/ 18 июля 2019
test ! -f README.md || echo 'Support OpenSource!' >> README.md

"Если README.md не существует, ничего не делать (и успешно завершить работу). В противном случае добавить текст в конец."

Если вы используете && вместо ||, тогдавы генерируете ошибку, когда файл не существует:

Makefile:42: recipe for target 'dostuff' failed
make: *** [dostuff] Error 1
0 голосов
/ 26 января 2019

Ответы, подобные ответу от @ mark-wilkins, использующего \ для продолжения строк и; прекратить их в оболочке или как в @kenorb, изменив это на одну строку, это хорошо, и это решит эту проблему.

есть более простой ответ на исходную проблему (как указал @ alexey-polonsky). Используйте флаг -f для rm, чтобы он не вызывал ошибку

rm -f myApp

это проще, быстрее и надежнее. Только будьте осторожны, чтобы не получить косую черту и пустую переменную

rm -f / $ (myAppPath) # НИКОГДА НЕ ДЕЛАЙТЕ ЭТОГО

Вы можете удалить свою систему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...