Question Comment faire pour que rm ne donne pas d'erreur si un fichier n'existe pas?


J'écris un fichier makefile qui va nettoyer certains fichiers inutiles à la fin de la compilation. Si une cible a déjà été créée, elle sautera bien sûr cette cible et le fichier inutile risque de ne pas exister. Donc, si je fais ceci:

rm lexer.ml interpparse.ml interpparse.mli

Je peux avoir des erreurs car l'un des fichiers n'existe pas. Y a-t-il un moyen de dire rm ignorer ces fichiers?

En lisant la page de manuel, je vois l’option suivante:

 -f          Attempt to remove the files without prompting for confirma-
             tion, regardless of the file's permissions.  If the file does
             not exist, do not display a diagnostic message or modify the
             exit status to reflect an error.  The -f option overrides any
             previous -i options.

Cela ressemble à presque ce que je veux, mais je ne suis pas vraiment sûr de la partie des autorisations. Y a-t-il un moyen de faire cela?


261
2017-11-27 16:43


origine


Avez-vous essayé quelques rm dans un bac à sable? Ça ressemble à -f fait exactement ce que vous voulez, indépendamment de la globulation. - JMD
Si les autorisations ne le permettent pas, rm sera avec le -f option encore essayer de le supprimer. Ça va échouer. Il ne vous dira pas que cela a échoué. Utile si le nom de fichier est une variable ou un glob. - LawrenceC


Réponses:


le -f l'option est certainement ce que vous voulez utiliser.

La confirmation à propos des autorisations de fichiers auxquelles il fait référence est la suivante:

$ touch myfile    
$ chmod 400 myfile
$ rm myfile       
rm: remove write-protected regular empty file `myfile'?

Alors rm vous avertira si vous essayez de supprimer un fichier sur lequel vous n’avez pas de droits d’écriture. Ceci est permis si vous avez des permissions en écriture sur le répertoire mais que c'est un peu bizarre, c'est pourquoi rm vous en avertit normalement.


221
2017-11-27 16:54



La plupart des systèmes, mais pas tous, demanderont (je pense). Certains exigent -i. - DaveParillo
Si vous voulez le message d'erreur, mais pas le code de sortie d'erreur, consultez la réponse par Giel Berkers. j'utilise set -e dans tous mes scripts bash pour que le script se termine après une commande donne une erreur. Je veux souvent un script pour me dire si rm a donné une erreur, mais continue quand même. continue. - cledoux


Une autre solution est celle-ci: https://stackoverflow.com/questions/11231937/bash-ignoring-error-for-a-particular-command

Ajoutez simplement une instruction OR après votre commande:

rm -rf my/dir || true

De cette façon, lorsque l'instruction n ° 1 échoue (erreur générée), exécutez l'instruction n ° 2, qui est simplement true.


77
2018-03-09 12:39



Il imprime l'erreur et continue l'exécution, ce qui était souhaité pour mon cas. - worldsayshi
Ou juste rm -rf my/dir ||: être encore plus concis (: est court pour true) - Godsmith
La meilleure solution à mon avis. Il est facile de voir ce qui se passe et pourquoi le code de résultat est ignoré. J'aime ça! - Mavamaarten


Je suis très en retard à la fête, mais je l'utilise tout le temps. Dans un makefile, ajoutez - au début d'une ligne pour ignorer la valeur de retour de cette ligne. Ainsi:

-rm lexer.ml interpparse.ml interpparse.mli

69
2017-12-23 23:12



Cela imprimera quand même l'erreur sur la console, ce qui vous apprend à ignorer les erreurs dans la sortie de make, ce qui n'est probablement pas ce que vous voulez. rm -rf est une meilleure option à mon avis. - Godsmith
@Godsmith Je préfère ignorer une erreur que de forcer la suppression récursive. Cela pourrait être très méchant. Et +1 pour la syntaxe spécifique au makefile - Daishi
Si rm -rf peut être "méchant", cela signifie que vous utilisez make en dehors d'un répertoire sous contrôle de version. Pourquoi? - Godsmith
Donnez un lien vers la documentation, s'il vous plaît. Pourrait trouver la description de cette fonctionnalité. - George Sovetov
@GeorgeSovetov gnu.org/software/make/manual/make.html#Errors - Robert Li


Si vous ne souhaitez pas utiliser l'option -f, une alternative est:

rm filethatdoesntexist 2> /dev/null 

Cela empêchera simplement l'impression des erreurs.


8
2018-06-12 19:46



Malheureusement, cela donnera toujours un code de sortie d'erreur. - Shaun McDonald


Si vous trouvez un moyen de glob les noms de fichiers, rm ne se plaindra pas s'il ne peut pas trouver un match. Donc quelque chose comme lexer.m* interpparse.*, etc. devrait fonctionner pour vous (faites attention à ne pas en supprimer trop, bien sûr). Aussi, -f est un moyen tout à fait raisonnable, tant que vous n'espérez pas que les autorisations de fichiers vous éviteront de supprimer un fichier que vous ne voulez pas - si vous ne souhaitez pas le supprimer, ne le mettez pas dans le dossier. liste.


7
2017-11-27 16:48



Le regroupement serait hors de question car il existe un fichier lexer.mll que je ne souhaite pas supprimer. Merci d'avoir montré pourquoi -f est raisonnable. Je suppose que j'ai tendance à être trop prudent après un trop nombreux égarés sudo rm -rf . - Jason Baker
Même pas plus restrictif lexer.m? ...? Ça attraperait lexer.ml et lexer.mz, mais non lexer.mll ou lexer.mla. - JMD
@JMD: Je suppose que cela dépend de votre shell et du support qu'il offre pour la globalisation. - Nick Bastin


L'option -f signifie que vous ne serez pas invité si quelque chose ne va pas comme prévu. Cela ne signifie pas que les autorisations ne sont pas prises en compte.

Si vous n'avez pas assez de privilèges pour supprimer un fichier, il ne sera pas supprimé.

MAISSi vous disposez de suffisamment de privilèges pour modifier vos privilèges, votre fichier sera supprimé. C'est le cas lorsque vous êtes propriétaire d'un fichier avec des autorisations en lecture seule pour le propriétaire (-r --------). En tant que propriétaire, vous pouvez chmod u+w, puis retirez-le: rm -f va supprimer ce fichier.


5
2017-11-27 19:27





Peut-être pourrait aider une ligne similaire avec:

touch fakefile.exe fakefile.o && rm *.o *.exe

Je sais que ce n'est pas très intelligent, mais ça fait le travail.


3
2018-03-11 10:36





Une alternative:

RmIfIsFile() {  for f in "$@"; do [ -f $f ] && rm $f; done; };  RmIfIsFile lexer.ml interpparse.ml interpparse.mli

Dommage que les Makefiles ne puissent pas partager les définitions de fonction shell entre les lignes.


2
2017-11-27 17:44



Avez-vous essayé d'utiliser \ (barre oblique inverse) à la fin d'une rangée pour le laisser continuer le suivant? - some
@some: Oui, ils peuvent être répartis sur plusieurs lignes, mais pour les partager entre les recettes, vous devez définir la définition dans une variable make. - reinierpost


Voici ce que j'utilise dans les scripts shell. Il cache le message d'erreur et le code d'erreur.

rm doesnotexist 2> /dev/null || echo > /dev/null

2
2018-06-11 13:55