rm -rf échoue si la suppression en parallèle

rm -rf échouera si quelque chose essaie de supprimer la même arborescence de files (je pense que rm énumère d'abord les files, puis les supprime).

Un test simple:

 # Terminal 1 for i in `seq 1 1000`; do mkdir -p /tmp/dirtest/$i; done # Now at the same time in terminal 1 and 2 rm -rf /tmp/dirtest 

Il y aura une sortie dans stderr, par exemple:

 ... rm: cannot remove directory `/tmp/dirtest/294': No such file or directory rm: cannot remove directory `/tmp/dirtest/297': No such file or directory rm: cannot remove directory `/tmp/dirtest/304': No such file or directory 

Je peux ignorer toute la sortie stderr en la redirigeant vers /dev/null , mais la suppression de /tmp/dirtest échoue en réalité! Une fois les deux commands terminées, /tmp/dirtest est toujours là.

Comment puis-je faire rm supprimer l'arborescence de directorys correctement et ignorer vraiment toutes les erreurs?

Méchant. Mais dans un sens, vous searchz des problèmes lorsque deux process concurrents manipulent une arborescence de directorys. Unix fournit des primitives pour la manipulation atomique d'un seul file, mais pas pour les arborescences de directorys entières.

Une solution de contournement simple serait pour votre script de renommer le directory avant de le supprimer. Étant donné que votre scénario d'utilisation comporte des scripts coopératifs, le nouveau nom est prévisible.

 mv /build/tree /build/tree.rm.$$ mkdir /build/tree rm -rf /build/tree.rm.$$ 

Peut-être que vous pouvez même faire le rm en arrière-plan plus tard, pendant que votre compilation effectue certaines tâches liées au processeur.

Je suis curieux de savoir comment le système de construction a fini comme ça. Êtes-vous capable de le changer? Au minimum, vous pouvez créer un drapeau qui permet aux scripts de savoir que l'autre est déjà en train de faire le travail …

 mkdir /tmp/flag.rmdirtest && rm -rf /tmp/dirtest && rmdir /tmp/flag.rmdirtest 

Il serait préférable de re-architecturer la chose afin que cela ne soit pas nécessaire.