W czystej sekcji mojego Makefile
próbuję sprawdzić, czy plik istnieje przed trwałym usunięciem. Używam tego kodu, ale otrzymuję błędy.
Co jest z tym nie tak?
if [ -a myApp ]
then
rm myApp
fi
Otrzymuję ten komunikat o błędzie
if [ -a myApp ]
/bin/sh: Syntax error: end of file unexpected (expecting "then")
make: *** [clean] Error 2
rm -rf myApp
może być alternatywą. Lub poprzedzając polecenie myślnikiem (-rm myApp
), aby make zignorował błąd z rm (wypisze jednak brzydki komunikat).Odpowiedzi:
Druga najczęstsza odpowiedź wspomina
ifeq
jednak, że nie wspomina, że muszą one znajdować się na tym samym poziomie, co nazwa celu, np. Aby pobrać plik tylko wtedy, gdy obecnie nie istnieje, można użyć następującego kodu:źródło
Dziwnie jest widzieć tak wielu ludzi używających do tego skryptów powłoki. Szukałem sposobu na użycie natywnej składni makefile, ponieważ piszę to poza jakimkolwiek celem. Możesz użyć
wildcard
funkcji, aby sprawdzić, czy plik istnieje:Aktualizacja:
Znalazłem sposób, który naprawdę mi odpowiada:
źródło
Makefile:133: *** unterminated call to function `wildcard': missing `)'. Stop.
$(wildcard pattern)
tak naprawdę robi. Zobacz link .FILE_EXISTS := $(or $(and $(wildcard $(PATH_TO_FILE)),1),0)
Problem występuje, gdy podzielisz polecenie na wiele linii. Możesz więc użyć znaku
\
na końcu linii do kontynuacji, jak powyżej, lub możesz uzyskać wszystko w jednej linii za pomocą&&
operatora w bash.Następnie możesz użyć
test
polecenia, aby sprawdzić, czy plik istnieje, np .:lub nie:
test
Jest równoważne[
poleceniu.i będzie działać tak, jak w oryginalnym przykładzie.
Zobacz:
help [
lubhelp test
dla dalszej składni.źródło
-s
jest to szczególny przypadekexists and has a size greater than zero
. Pytanie, tak jak zostało napisane, jest niezależne od rozmiaru, więc istnienie powinno być sprawdzane przy użyciutest -e
pliku lub-d
katalogu. Puste pliki mogą być szczególnie przydatne jako (z braku lepszego terminu) wskaźniki / wskaźniki, które mogą być całkiem istotne dlamake
.-f
domyślnie, ponieważ jest bardziej powszechny w użyciu.test
do systemu Windows?|| true
na końcu, aby polecenie zwracało wartość true, gdy plik nie istnieje.test -f myApp || CMD
, zwróć uwagę na||
, więc jeśli-f
nie powiedzie się - nie istnieje (||
), uruchom polecenie. Czy jest sens?Kontynuacja może wymagać odwrotnego ukośnika na końcu linii (chociaż może to zależy od wersji make):
źródło
make
nowej linii będzie nowe polecenie bash. Głównym zastrzeżeniem, innym niż uciążliwość wynikająca z posiadania wielu znaków\
na końcu linii, jest to, że każde polecenie musi być zakończone poleceniem,;
które w przeciwnym razie byłoby ukryte w bash.Lub po prostu umieść to w jednej linii, tak jak
make
lubi:źródło
Brak średnika
Zakładam jednak, że przed usunięciem sprawdzasz istnienie, aby zapobiec wyświetleniu komunikatu o błędzie. Jeśli tak, możesz po prostu użyć polecenia
rm -f myApp
„wymusza” usunięcie, tj. Nie wyświetla błędu, jeśli plik nie istnieje.źródło
wyniki realizacji:
źródło
echo -n yes
Zmienia sukcestest
na ciągyes
bez NL. Następnieifeq
można porównać to z zakodowanym na stałeyes
. Wszystko dlatego, żeifeq
chce porównać ciąg znaków, a nie stan sukcesu polecenia powłoki.Rozwiązanie jednoprzewodowe:
Rozwiązanie jednokreskowe z działaniem błędu:
Przykład użyty w moich
make clean
dyrektywach:I
make clean
zawsze działa bez żadnych komunikatów o błędach!źródło
-rm myfile
główny myślnik mówiący make, aby zignorować każdy błąd.@[ -f 'myfile' ] && rm myfile
„Jeśli plik README.md nie istnieje, nic nie rób (i zakończ pomyślnie). W przeciwnym razie dołącz tekst na końcu”.
Jeśli użyjesz
&&
zamiast||
tego, wygenerujesz błąd, gdy plik nie istnieje:źródło
Próbowałem:
I pozytywny przypadek zadziałał, ale moja powłoka ubuntu bash nazywa to PRAWDA i psuje kopię:
Po otrzymaniu tego błędu wyszukuję w Google, jak sprawdzić, czy plik istnieje w make i to jest odpowiedź ...
źródło
To rozwiązanie zamieszczone powyżej działa najlepiej. Ale upewnij się, że nie określasz przypisania PATH_TO_FILE, np.
To musi być
źródło
Odpowiedzi takie jak ta z @ mark-wilkins używająca \ do kontynuowania linii i; zakończenie ich w powłoce lub jak te z @kenorb zmiana tego na jedną linię są dobre i naprawią ten problem.
istnieje prostsza odpowiedź na pierwotny problem (jak wskazał @ alexey-polonsky). Użyj flagi -f do rm, aby nie wywoływała błędu
jest to prostsze, szybsze i bardziej niezawodne. Uważaj tylko, aby nie zakończyć się ukośnikiem i pustą zmienną
rm -f / $ (myAppPath)# NIGDY TEGO NIE ROBIĆmożesz skończyć usunięciem systemu.
źródło
rm
; BTW, jestem prawie pewien, żerm -f /$(myAppPath)
to też nie spowoduje żadnych szkód, ponieważ/
jest to katalog, którego-r
brakuje.rm -f
, np. Może chciećrm
użyć zmiennej.