Rm n'a-t-il pas signalé qu'un fichier est manquant?

39

J'ai un script bash que je souhaite supprimer des fichiers de divers répertoires. Souvent, ils ne seront pas là parce qu'ils n'ont pas été générés et c'est très bien. Existe-t-il un moyen d'obtenir que le script ne signale pas cette erreur, mais si rm a une autre sortie pour le signaler?

Sinon, existe-t-il une meilleure commande à utiliser pour supprimer le fichier qui sera moins bruyant?

papillotement
la source

Réponses:

67

Utilisez l' -foption. Il ignorera silencieusement les fichiers inexistants.

De man rm:

   -f, --force
          ignore nonexistent files and arguments, never prompt

[La partie "ne jamais demander" signifie que (a) -fremplace toute option -iou -Ioption précédemment spécifiée , et (b) les fichiers protégés en écriture seront supprimés sans demander.]

Exemple

Sans -f, rmse plaindra des fichiers manquants:

$ rm nonesuch
rm: cannot remove ‘nonesuch’: No such file or directory

Avec -f, il sera silencieux:

$ rm -f nonesuch
$
John1024
la source
4
Oh, je nouveau qui n'a pas demandé de suppression, je n'ai pas réalisé qu'il ignorait également les inexistants. J'ai totalement ignoré cela en regardant l'homme. :-) Je vous remercie. Je marquerai cela comme la réponse dès que je serai autorisé.
flickerfly
9

Si votre exigence est de rmne pas se plaindre de fichiers manquants, mais que vous souhaitez également toute autre sortie rm, ma suggestion serait de tester d'abord l'existence du fichier cible, et d'appeler uniquement rm( sans l' -findicateur) si le fichier existe réellement.

# rest of script
# ...
[ -e "$file" ] && rm "$file"
# ...
# rest of script

L'appel rm -fsur un fichier qui, par exemple, ne dispose pas d'autorisations d'écriture utilisateur, supprimera le fichier et n'émettra pas non plus l'invite normale pour ce scénario.

Dans le cas où vous vouliez utiliser la même idée avec plusieurs fichiers, je créerais une définition de fonction, comme:

qrm() {
  for f
  do
    [ -e "$f" ] && rm "$f"
  done
}

Utilisez-le comme: qrm file1 file2-does-not-exist *.txt etc here

Jeff Schaller
la source
1
Cela vaut la peine d'être conscient de la très faible chance d'une condition de concurrence critique où le fichier est supprimé (ou créé) entre le test et la suppression, mais je ne peux pas imaginer que cela soit pertinent dans une situation typique où l'on utiliserait un script shell .
David Z
7

Vous avez déclaré que vous souhaitiez toujours voir d'autres sorties de la rmcommande lorsque vous l'exécutez, mais l'utilisation de l' -foption les supprimera. Vous devrez filtrer STDERR pour ce que vous voulez, ce qui est un peu délicat, étant donné que vous voulez que tout le reste s'affiche.

Vous voudrez utiliser une commande comme celle-ci:

rm -f filename 3>&1 1>&2 2>&3 3>&- | grep -v 'No such file or directory'

Commande expliquée:

  • -f l'argument est de forcer et de ne pas demander de confirmation ou d'erreurs
  • 3>&1 1>&2 2>&3 3>&-consiste à basculer entre STDOUT et STDERR pour le filtrage (vous pouvez en savoir plus ici si vous le souhaitez
  • | grep -v 'No such file or directory' filtre le message que vous ne voulez pas voir

Maintenant, si vous vouliez simplement supprimer complètement les messages d'erreur, vous pouvez exécuter la commande suivante:

rm filename 2> /dev/null

Cette commande redirige STDERR vers / dev / null afin que vous ne le voyiez pas lorsque vous exécutez la commande.

BriGuy
la source
1
(AFAICS) rmsans -vjamais sortir sur stdout, seulement stderr, donc dans ce cas, vous pourriez juste 2>&1 | grepsans la danse qui est utile plus généralement,
dave_thompson_085
4

Comme alternative, vous pouvez utiliser la findcommande avec l' -deleteoption. Cela ne supprimera (évidemment) que les fichiers qu'il trouve afin de ne jamais avertir s'il n'y en a pas. Un exemple pourrait être:

find /var/log/triffids/ -name "*.log" -mtime 30 -delete

qui rechercherait le /var/log/triffids/répertoire et supprimerait tous les fichiers avec le .logsuffixe qui n'ont pas été modifiés depuis plus de 30 jours.

C'est toujours une bonne idée d'exécuter ces commandes sans l' -deleteoption d'abord, pour vous assurer qu'il trouve les fichiers que vous attendez.

seumasmac
la source
J'aime cette option et envisagerai un changement. Merci de le partager.
flickerfly
3

Cochez l' option --force( -f) de rm:

-f, --force

ignorer les fichiers et arguments inexistants, ne jamais demander

heemayl
la source
2

C'est un hack, mais vous pouvez toujours touchsupprimer le fichier. S'il n'existe pas, il sera créé, vous rmpouvez donc le supprimer.

matega
la source
J'aime cela, sauf pour les performances - à quel point est-il coûteux de toucher plusieurs K de fichiers au lieu de supprimer uniquement ceux qui n'existent pas?
Dani_l
0

Vous pouvez utiliser -fcomme bon vous semble, selon la page de manuel:

Essayez de supprimer les fichiers sans demander de confirmation, quelles que soient les autorisations du fichier. Si le fichier n'existe pas, n'affichez pas de message de diagnostic ou modifiez l'état de sortie pour refléter une erreur. Souvenez-vous également que l'option -f remplace toutes les options -i précédentes.

rm -f xyz-directory

ne vous demandera rien et fera exactement ce que vous voulez.

Ankit Jain
la source
-1

Il y a deux façons principales: Si vous ajoutez l'option -f, elle n'affichera pas l'erreur "n'existe pas" et deux: (fonctionne pour presque toutes les commandes) au lieu de simplement faire "la commande" faire "la commande 2> / dev / null "où" la commande "est la commande que vous effectuez.

John
la source
1
J'évitais la tuyauterie parce que je ne veux pas perdre d'autres erreurs qui pourraient survenir. Je ne sais pas ce que ce serait.
flickerfly