script shell pour supprimer un fichier s'il existe déjà

205

Je travaille sur des trucs où je stocke des données dans un fichier. Mais chaque fois que j'exécute le script, il est ajouté au fichier précédent.

Je souhaite obtenir de l'aide sur la façon de supprimer le fichier s'il existe déjà.

Niks
la source
3
Vérifiez si le fichier existe ... puis appelez rm $my_file, non? Quelle coque utilisez-vous?
Chris Sprague

Réponses:

207

Ne vous inquiétez pas de vérifier si le fichier existe, essayez simplement de le supprimer.

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

Notez que la deuxième commande échouera (retourne un état de sortie différent de zéro) si le fichier n'existait pas, mais la première réussira grâce à l' option -f(abréviation de --force). Selon la situation, cela peut être un détail important.

Mais plus probablement, si vous ajoutez au fichier, c'est parce que votre script utilise >>pour rediriger quelque chose dans le fichier. Remplacez simplement >>par >. C'est difficile à dire puisque vous n'avez fourni aucun code.

Notez que vous pouvez faire quelque chose comme test -f /p/a/t/h && rm /p/a/t/h, mais cela est complètement inutile. Il est tout à fait possible que le test retourne vrai mais le / p / a / t / h échouera avant que vous essayiez de le supprimer, ou pire le test échouera et le / p / a / t / h sera créé avant d'exécuter la commande suivante qui s'attend à ce qu'elle n'existe pas. Tenter ceci est une condition de course classique. Ne fais pas ça.

William Pursell
la source
5
Cela n'est pas utile s'ils ont besoin de savoir s'il existait et a été supprimé. Manger du stderr ne fournit pas cela. Ne pas gérer l'existence ne vous permet pas d'exécuter un script plus large sans échouer.
uchuugaka
1
@uchuugaka C'est une solution simple lorsque vous ne vous souciez pas de savoir si un fichier est là, tout ce que vous voulez est de vous assurer qu'il n'y est pas .
Lukas Liesis
De bonnes réponses devraient être à venir et complètes sur les effets secondaires est la généralisation de mon message, mais les scripts shell veulent souvent savoir ce qui est ou n'est pas trouvé et ce qui est ou ne fonctionne pas.
uchuugaka
rm /p/a/t/h 2> /dev/nullne conservera pas le code de retour ( echo $?) à 0 si le fichier n'existait pas. Cela ferait échouer les tâches Jenkins simplement parce que nous avons essayé de supprimer un fichier inexistant.
ViFI
@uchuugaka - J'ai évité de répondre à ce commentaire pendant un certain temps, mais il doit être résolu. Vérifier si le fichier existe avant de le supprimer est toujours une mauvaise idée. Voir le dernier paragraphe de ma réponse. Il existe une condition de race inhérente qui ne peut tout simplement pas être évitée en faisant ce genre de chose. Si vous ne voulez pas écraser un fichier existant, vous pouvez essayer une magie spécifique au shell (comme noclobberdans bash), ou peut-être modifier le fichier existant pour que la redirection échoue si le fichier existe (n'évite pas la condition de concurrence), mais tout ce que cela fera est de rendre les bogues plus subtils.
William Pursell le
134

Une autre commande d'une ligne que j'ai utilisée est:

[ -e file ] && rm file
liwp_Stephen
la source
12
Ou bien: [ ! -e fichier] || fichier rm. Cette version renvoie 0 au lieu d'une erreur.
nawfel bgh
@nawfelbgh Merci, c'est parfait pour enchaîner dans un script plus long.
Abe
Pour ceux qui ne sont pas très observateurs, comme moi, il y a un espace entre le crochet gauche et le point d'exclamation, ce qui est nécessaire pour que la commande fonctionne
geo909
92

Vous pouvez utiliser ceci:

#!/bin/bash

file="file_you_want_to_delete"

if [ -f $file ] ; then
    rm $file
fi
Jindra Helcl
la source
4
Cela devrait être la réponse choisie.
ingernet
Simple et facile à lire et garantit également que echo $?ne donne pas 1 si le fichier n'existe pas.
ViFI
Si nécessaire, vous pouvez également le faire en une seule ligne, voir ma réponse ci-dessous.
nbeuchat le
Ne devriez-vous pas citer "$file"?
stephanmg
Si vous voulez traiter des fichiers aux noms étranges, alors oui, vous pouvez citer en toute sécurité. Mais par souci de simplicité, je préfère laisser la réponse telle quelle.
Jindra Helcl le
70

Si vous voulez ignorer l'étape pour vérifier si le fichier existe ou non, vous pouvez utiliser une commande assez simple, qui supprimera le fichier s'il existe et ne lèvera pas d'erreur s'il est inexistant.

 rm -f xyz.csv
greperror
la source
1
Ceci est juste une copie d'une partie de la réponse la mieux notée, de 2015.
pardonner
16
la réponse principale n'expliquait pas qu'avec le, -fcela ne générerait pas d'erreur. Cette réponse m'a aidé, merci.
Doug
D'accord avec Doug bien que cela semble être un bon cas d'utilisation pour une modification de type wiki d'une réponse.
Philip
21

Un script shell à une ligne pour supprimer un fichier s'il existe déjà (basé sur la réponse de Jindra Helcl):

[ -f file ] && rm file

ou avec une variable:

#!/bin/bash

file="/path/to/file.ext"
[ -f $file ] && rm $file
nbeuchat
la source
13

Quelque chose comme ça fonctionnerait

#!/bin/sh

if [ -fe FILE ]
then 
    rm FILE
fi 

-f vérifie s'il s'agit d'un fichier normal

-e vérifie si le fichier existe

Introduction à if pour plus d'informations

EDIT: -e utilisé avec -f est redondant, fo utiliser -f seul devrait fonctionner aussi

P1kachu
la source
-aest obsolète, utilisez à la -eplace.
mziccard
mon mauvais, fixe. Merci @mziccard
P1kachu
cela jettera des erreurs sur des répertoires ou des liens ou d'autres fichiers non normaux. Il est à mon avis meilleur / plus sûr à utiliser -f.
Jindra Helcl du
1
D'accord. encore, l' -een -feest redondant, comme -fvérifie également l'existence du fichier pour autant que je sais ..
Jindra Helcl
Si je modifie, je vais juste faire un double de votre réponse, mais je vais le préciser
P1kachu
4

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

De plus, si vous redirigez votre sortie avec >au lieu de >>cela, il écrasera le fichier précédent

nLee
la source
3
ce n'est pas un one-liner, désolé mais celui de @liwp_Stephen l'est.
fiorentinoing
Même s'il est correctement cité, cela casse si filec'est quelque chose comme5 -lt 2
William Pursell