script shell per rimuovere un file se esiste già


183

Sto lavorando su alcune cose in cui sto memorizzando i dati in un file. Ma ogni volta che eseguo lo script viene aggiunto al file precedente.

Voglio aiuto su come posso rimuovere il file se esiste già.


3
Controlla se il file esiste ... e poi chiama rm $my_file, giusto? Che shell stai usando?
Chris Sprague,

Risposte:


184

Non preoccuparti di controllare se il file esiste, prova solo a rimuoverlo.

rm -f /p/a/t/h
# or
rm /p/a/t/h 2> /dev/null

Si noti che il secondo comando fallirà (restituirà uno stato di uscita diverso da zero) se il file non esistesse, ma il primo avrà esito positivo grazie all'opzione -f(abbreviazione di --force). A seconda della situazione, questo può essere un dettaglio importante.

Ma più probabilmente, se stai aggiungendo al file è perché lo script sta usando >>per reindirizzare qualcosa nel file. Sostituisci >>con >. È difficile da dire poiché non hai fornito alcun codice.

Nota che puoi fare qualcosa del genere test -f /p/a/t/h && rm /p/a/t/h, ma farlo è completamente inutile. È possibile che il test ritorni vero ma il / p / a / t / h non esisterà prima di provare a rimuoverlo, o peggio il test fallirà e verrà creato il / p / a / t / h prima di eseguire il comando successivo che prevede che non esista. Tentare questa è una condizione di gara classica. Non farlo


5
Questo non è utile se hanno bisogno di sapere se esisteva ed è stato eliminato. Mangiare stderr non lo fornisce. Non gestire l'esistenza non consente di eseguire uno script più ampio senza errori.
Uchuugaka,

@uchuugaka Questa è una soluzione semplice quando non ti importa se c'è un file, tutto quello che vuoi è assicurarti che non sia lì.
Lukas Liesis,

Buone risposte dovrebbero essere imminenti e complete sugli effetti collaterali è la generalizzazione del mio messaggio, ma gli script di shell spesso vogliono sapere cosa si trova o non si trova e cosa si fa o non si agisce.
Uchuugaka,

rm /p/a/t/h 2> /dev/nullnon manterrà il codice di ritorno ( echo $?) come 0 se il file non esistesse. Ciò renderebbe i lavori di Jenkins falliti solo perché abbiamo tentato di eliminare un file inesistente.
ViFI,

@uchuugaka - Ho evitato di rispondere a questo commento per un bel po 'di tempo, ma deve essere affrontato. Controllare se il file esiste prima di eliminarlo è sempre una cattiva idea. Vedi l'ultimo paragrafo della mia risposta. C'è una condizione di razza intrinseca che semplicemente non può essere evitata facendo quel genere di cose. Se non vuoi sovrascrivere un file esistente, puoi provare un po 'di magia specifica della shell (come noclobberin bash), o magari modificare il file esistente in modo che il reindirizzamento fallisca se il file esiste (non evita le condizioni della gara), ma tutto ciò che farà è rendere i bug più sottili.
William Pursell,

127

Un altro comando a una riga che ho usato è:

[ -e file ] && rm file

11
O in alternativa: [! -e file] || file rm. Questa versione restituisce 0 invece di un errore.
nawfel bgh

@nawfelbgh Grazie, è ottimo per concatenarsi in una sceneggiatura più lunga.
Abe,

83

Puoi usare questo:

#!/bin/bash

file="file_you_want_to_delete"

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

4
Questa dovrebbe essere la risposta selezionata.
Ingernet,

Semplice e facile da leggere e garantisce anche che echo $?non dia 1 se il file non esiste.
ViFI,

Se necessario, puoi anche farlo come una linea, vedi la mia risposta di seguito.
Nbeuchat,

65

Se si desidera ignorare il passaggio per verificare se il file esiste o meno, è possibile utilizzare un comando abbastanza semplice, che eliminerà il file se esiste e non genererà un errore se non esiste.

 rm -f xyz.csv

1
Questo è solo un duplicato di parte della risposta più votata, dal 2015.
forgivenson,

16
la risposta principale non ha spiegato che con -fesso non avrebbe generato un errore. Questa risposta mi ha aiutato, grazie.
Doug

Concordo con Doug anche se questo sembra un buon caso d'uso per una modifica simile a wiki di una risposta.
Filippo,

16

Uno script shell di una riga per rimuovere un file se esiste già (basato sulla risposta di Jindra Helcl):

[ -f file ] && rm file

o con una variabile:

#!/bin/bash

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

13

Qualcosa del genere avrebbe funzionato

#!/bin/sh

if [ -fe FILE ]
then 
    rm FILE
fi 

-f controlla se è un file normale

-e controlla se il file esiste

Introduzione a if per ulteriori informazioni

EDIT: -e usato con -f è ridondante, anche usando -f da solo dovrebbe funzionare


-aè deprecato, utilizzare -einvece.
mziccard,

mio cattivo, risolto. Grazie @mziccard
P1kachu,

questo genererà errori su directory o collegamenti o altri file non normali. È meglio / più sicuro da usare -f.
Jindra Helcl,

1
ok. tuttavia, -ein -feè ridondante, poiché -fcontrolla anche l'esistenza del file per quanto ne so ..
Jindra Helcl

Se modifico, farò solo un duplicato della tua risposta, ma lo
preciserò

4

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

Inoltre, se si reindirizza l'output con >invece di >>esso sovrascriverà il file precedente


3
questo non è un one-liner, mi dispiace ma quello di @liwp_Stephen è quello.
Fiorentino

Anche se correttamente citato, questo si interrompe se fileè qualcosa del genere5 -lt 2
William Pursell,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.