skrypt powłoki, aby usunąć plik, jeśli już istnieje
183
Pracuję nad niektórymi rzeczami, w których przechowuję dane w pliku. Ale za każdym razem, gdy uruchamiam skrypt, zostaje on dołączony do poprzedniego pliku.
Chcę uzyskać pomoc w usunięciu pliku, jeśli już istnieje.
Nie zawracaj sobie głowy sprawdzaniem, czy plik istnieje, po prostu spróbuj go usunąć.
rm -f /p/a/t/h
# or
rm /p/a/t/h 2>/dev/null
Zauważ, że drugie polecenie zakończy się niepowodzeniem (zwróci niezerowy status wyjścia), jeśli plik nie istniał, ale pierwsze odniesie sukces dzięki opcji -f(skrót od --force). W zależności od sytuacji może to być ważny szczegół.
Ale bardziej prawdopodobne jest, że jeśli dołączasz się do pliku, dzieje się tak dlatego, że Twój skrypt >>przekierowuje coś do pliku. Wystarczy wymienić >>z >. Trudno powiedzieć, ponieważ nie podałeś kodu.
Pamiętaj, że możesz zrobić coś takiego test -f /p/a/t/h && rm /p/a/t/h, ale jest to całkowicie bezcelowe. Jest całkiem możliwe, że test zwróci wartość true, ale / p / a / t / h nie będzie istniał przed próbą jego usunięcia, lub gorzej test zakończy się niepowodzeniem i / p / a / t / h zostanie utworzony przed wykonaniem następnego polecenia, które oczekuje, że nie będzie istnieć. Próba tego jest klasycznym warunkiem wyścigu. Nie rób tego
Nie jest to pomocne, jeśli muszą wiedzieć, czy istniał i został usunięty. Jedzenie stderr tego nie zapewnia. Brak obsługi istnienia nie pozwala na szersze uruchomienie skryptu bez niepowodzenia.
uchuugaka
@uchuugaka To proste rozwiązanie, gdy nie obchodzi Cię, czy plik tam jest, wszystko, czego chcesz, to upewnić się, że go nie ma.
Lukas Liesis
Nadchodzące dobre odpowiedzi powinny być wyczerpujące, a efektem ubocznym jest uogólnienie mojej wiadomości, ale skrypty powłoki często chcą wiedzieć, co znajduje się, a czego nie, a co jest lub nie.
uchuugaka
rm /p/a/t/h 2> /dev/nullnie zachowa kodu powrotu ( echo $?) jako 0, jeśli plik nie istnieje. To sprawiłoby, że Jenkins byłby w pewnym sensie niepowodzeniem tylko dlatego, że próbowaliśmy usunąć nieistniejący plik.
ViFI
@uchuugaka - Długo unikałem odpowiedzi na ten komentarz, ale należy się nim zająć. Sprawdzanie, czy plik istnieje przed jego usunięciem, jest zawsze złym pomysłem. Zobacz ostatni akapit mojej odpowiedzi. Istnieje nieodłączny warunek rasowy, którego po prostu nie można uniknąć, robiąc takie rzeczy. Jeśli nie chcesz nadpisywać istniejącego pliku, możesz spróbować magii specyficznej dla powłoki (jak noclobberw bash), lub może przeskoczyć istniejący plik, aby przekierowanie nie powiodło się, jeśli plik istnieje (nie omija warunków wyścigu), ale wystarczy, że błędy będą bardziej subtelne.
Prosty i łatwy do odczytania, a także zapewnia, że echo $?nie daje 1, jeśli plik nie istnieje.
ViFI
W razie potrzeby możesz to zrobić jako jeden wiersz, patrz moja odpowiedź poniżej.
nbeuchat
65
Jeśli chcesz zignorować krok, aby sprawdzić, czy plik istnieje, czy nie, możesz użyć dość łatwego polecenia, które usunie plik, jeśli istnieje, i nie wyśle błędu, jeśli nie istnieje.
rm $my_file
, prawda? Jakiej powłoki używasz?Odpowiedzi:
Nie zawracaj sobie głowy sprawdzaniem, czy plik istnieje, po prostu spróbuj go usunąć.
Zauważ, że drugie polecenie zakończy się niepowodzeniem (zwróci niezerowy status wyjścia), jeśli plik nie istniał, ale pierwsze odniesie sukces dzięki opcji
-f
(skrót od--force
). W zależności od sytuacji może to być ważny szczegół.Ale bardziej prawdopodobne jest, że jeśli dołączasz się do pliku, dzieje się tak dlatego, że Twój skrypt
>>
przekierowuje coś do pliku. Wystarczy wymienić>>
z>
. Trudno powiedzieć, ponieważ nie podałeś kodu.Pamiętaj, że możesz zrobić coś takiego
test -f /p/a/t/h && rm /p/a/t/h
, ale jest to całkowicie bezcelowe. Jest całkiem możliwe, że test zwróci wartość true, ale / p / a / t / h nie będzie istniał przed próbą jego usunięcia, lub gorzej test zakończy się niepowodzeniem i / p / a / t / h zostanie utworzony przed wykonaniem następnego polecenia, które oczekuje, że nie będzie istnieć. Próba tego jest klasycznym warunkiem wyścigu. Nie rób tegoźródło
rm /p/a/t/h 2> /dev/null
nie zachowa kodu powrotu (echo $?
) jako 0, jeśli plik nie istnieje. To sprawiłoby, że Jenkins byłby w pewnym sensie niepowodzeniem tylko dlatego, że próbowaliśmy usunąć nieistniejący plik.noclobber
w bash), lub może przeskoczyć istniejący plik, aby przekierowanie nie powiodło się, jeśli plik istnieje (nie omija warunków wyścigu), ale wystarczy, że błędy będą bardziej subtelne.Innym poleceniem w jednym wierszu jest:
źródło
Możesz użyć tego:
źródło
echo $?
nie daje 1, jeśli plik nie istnieje.Jeśli chcesz zignorować krok, aby sprawdzić, czy plik istnieje, czy nie, możesz użyć dość łatwego polecenia, które usunie plik, jeśli istnieje, i nie wyśle błędu, jeśli nie istnieje.
źródło
-f
temu nie rzuci błędu. Ta odpowiedź pomogła mi, dziękuję.Skrypt powłoki jednowierszowej, aby usunąć plik, jeśli już istnieje (na podstawie odpowiedzi Jindry Helcl):
[ -f file ] && rm file
lub ze zmienną:
źródło
Coś takiego działałoby
-f sprawdza, czy jest to zwykły plik
-e sprawdza, czy plik istnieje
EDYCJA: -e użyte z -f jest redundantne, dla samego użycia -f też powinno działać
źródło
-a
jest przestarzałe, użyj-e
zamiast niego.-f
.-e
w-fe
jest zbędna, jak-f
również sprawdza istnienie pliku jako o ile wiem ..if [ $( ls <file> ) ]; then rm <file>; fi
Ponadto, jeśli przekierujesz dane wyjściowe,
>
zamiast>>
tego zastąpi poprzedni plikźródło
file
jest coś takiego5 -lt 2