option rm pour échouer sur des files inexistants

La page man de rm dans GNU coreutils 8.12.197-032bb décrit l'option -f ou --force comme "ignore les files inexistants, ne request jamais". Sans cette option, elle supprimera les files existants, n'invitera jamais et returnnera un code de sortie différent de zéro si aucun des files spécifiés n'existait. Je voudrais préserver les files si l' un des files spécifiés n'existe pas . Quelle est la manière la plus simple de faire ça?

Le cas d'utilisation est la security : Si j'essaie de supprimer un file qui n'existe pas, cela peut être parce qu'il y a une attente non valide (ou un simple bug) dans la command. Par exemple, le fameux rm -rf /usr /lib/nvidia-current/xorg/xorg aurait pu être évité de plusieurs façons, l'une d'entre elles étant une option (évidemment, à less que l'user par une incroyable coïncidence ait /lib/nvidia-current/xorg/xorg ), et un autre est d' utiliser Plus de Citations ™ . Cependant, les citations ne sont pas toujours suffisantes. Par exemple, considérons ssh host '/bin/rm some paths; /bin/bash foo.sh' ssh host '/bin/rm some paths; /bin/bash foo.sh' – Si j'avais oublié le point-virgule ou inséré à peu près n'importe quel autre symbole comme le colon ou la virgule, il aurait essayé de supprimer /bin/bash et ~/foo.sh

J'utilise ce genre de chose:

 mkdir DELETE && mv "some" "paths" DELETE && rm -rf DELETE 

Pour un seul path:

 mv /some/path DELETE && rm -rf DELETE 

Encore mieux, tapez la rm command sur une command line séparée: mv /some/path DELETE Entrez rm -rf DELETE Enter . De cette façon, la seule command rm qui se trouve dans l'historique de votre shell se trouve dans un file nommé DELETE . Si vous avez supprimé une ancienne version d'un file, vous ne risquez pas de supprimer la nouvelle version en appuyant accidentellement sur le nombre de fois incorrect puis Entrée .

Si vous voulez automatiser un peu:

 mv_to_DELETE () { mkdir DELETE && mv -- "$@" DELETE/ } mv_to_DELETE "some" "paths" rm -rf DELETE 

Quelque chose comme

 paths=("some" "paths") for path in "${paths[@]}" do [ -e "$path" ] || exit 1 done 

avant chaque command rm est beaucoup plus compliquée pour un débutant, et dépend des baies Bash.

 for path in "some" "paths" do [ -e "$path" ] || exit 1 done 

est plus portable, mais signifie dupliquer la list des paths dans la boucle et la command rm . Et le stockage de tous les paths dans la même variable de string signifie que le script ne prend plus en charge aucun des caractères IFS dans les noms de file.