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.


3
Sprawdź, czy plik istnieje ... a następnie zadzwoń rm $my_file, prawda? Jakiej powłoki używasz?
Chris Sprague,

Odpowiedzi:


184

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


5
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.
William Pursell

127

Innym poleceniem w jednym wierszu jest:

[ -e file ] && rm file

11
Lub alternatywnie: [! -e plik] || plik rm. Ta wersja zwraca 0 zamiast błędu.
nawfel bgh

@nawfelbgh Dzięki, jest to świetne do łączenia w dłuższe skrypty.
Abe

83

Możesz użyć tego:

#!/bin/bash

file="file_you_want_to_delete"

if [ -f $file ] ; then
    rm $file
fi

4
To powinna być wybrana odpowiedź.
ingernet

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 -f xyz.csv

1
To tylko kopia części najwyżej ocenianej odpowiedzi z 2015 roku.
sorry

16
główna odpowiedź nie tłumaczyła, że ​​dzięki -ftemu nie rzuci błędu. Ta odpowiedź pomogła mi, dziękuję.
Doug

Zgadzam się z Dougiem, chociaż wydaje się, że jest to dobry przypadek użycia dla edycji odpowiedzi typu wiki.
Philip

16

Skrypt powłoki jednowierszowej, aby usunąć plik, jeśli już istnieje (na podstawie odpowiedzi Jindry Helcl):

[ -f file ] && rm file

lub ze zmienną:

#!/bin/bash

file="/path/to/file.ext"
[ -f $file ] && rm $file

13

Coś takiego działałoby

#!/bin/sh

if [ -fe FILE ]
then 
    rm FILE
fi 

-f sprawdza, czy jest to zwykły plik

-e sprawdza, czy plik istnieje

Wprowadzenie do if, aby uzyskać więcej informacji

EDYCJA: -e użyte z -f jest redundantne, dla samego użycia -f też powinno działać


-ajest przestarzałe, użyj -ezamiast niego.
mziccard,

mój zły, naprawiony. Dzięki @mziccard
P1kachu

spowoduje to błędy w katalogach lub linkach lub innych niestandardowych plikach. Imho jest lepszy / bezpieczniejszy w użyciu -f.
Jindra Helcl

1
dobrze. Mimo to, -ew -fejest zbędna, jak -frównież sprawdza istnienie pliku jako o ile wiem ..
Jindra Helcl

Jeśli
zmienię

4

if [ $( ls <file> ) ]; then rm <file>; fi

Ponadto, jeśli przekierujesz dane wyjściowe, >zamiast >>tego zastąpi poprzedni plik


3
przepraszam, ale nie jest to jedna linijka, ale taka jest @liwp_Stephen.
fiorentinoing

Nawet jeśli jest właściwie cytowany, to łamie się, jeśli filejest coś takiego5 -lt 2
William Pursell
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.