2010-12-10 59 views
3

Serait-il possible d'exécuter une commande bash via SSH qui boucle sur plusieurs répertoires EXCEPT 3 ou 4 que je spécifie? Quelque chose comme:Commande SSH pour faire défiler les répertoires SAUF quelques-uns spécifiés

Supprimer public_html/outdated/ pour tous les répertoires dans /home/ sauf /home/exception1/, /home/exception2/ et /home/exception3/

Je suis sur un HostGator serveur dédié Linux.

+0

Vous avez probablement ne pas l'intention d'avoir une barre oblique initiale sur 'public_html/jour /' –

+0

Vous avez raison, je vous remercie @Dennis Williamson je l'ai corrigé. – filip

Répondre

2

Le test!

shopt -s extglob 
rm -rf /home/!(exception1|exception2|exception3)/public_html/outdated/ 
+0

c'est magnifique et simple. Je ne suis pas sûr si vous avez besoin de répéter le répertoire 'home' dans la liste des exceptions si. Au moins cela n'a pas fonctionné pour moi jusqu'à ce que je l'ai changé juste '(exception1 | exception2 | exception3)'. – filip

+0

AUSSI j'avais besoin d'exécuter 'shopt -s extglob' pour que l'opérateur'! 'Fonctionne, mais ça marche très bien maintenant. – filip

+0

Désolé, je ne faisais que copier et coller de votre question sans y penser. Aussi, désolé j'ai oublié de mentionner 'extglob'. Je vais corriger ma réponse. –

1

Voici une solution simple - il y a probablement de meilleures façons de le faire.

cd /home 
ls */public_html/outdated 

devriez-vous tous ces; vous pouvez utiliser grep -v pour supprimer les lignes de cette

ls */public_html/outdated | grep -Ev ^exception1/ | grep -Ev ^exception2/ | grep -Ev ^exception3/ 

puis utiliser pour alimenter ces accents graves dans rm -rf

rm -rf `ls */public_html/outdated | grep -Ev ^exception1/ | grep -Ev ^exception2/ | grep -Ev ^exception3/` 

Il est évident que vous devez exécuter l'étape intermédiaire pour vérifier la liste avant de les supprimer réellement !

Notez que cela peut ne pas fonctionner si l'un de vos répertoires contient des espaces - bien que les noms d'utilisateurs dans/home ne le soient pas. Le moyen le plus sûr de le faire est d'utiliser find. (Il y a probablement un moyen de faire de l'exclusion avec découverte mais je ne me souviens jamais.)

3

Tout cela est une ligne, mais j'ai divisé ici pour une meilleure lisibilité

find /home 
    \(-wholename '/home/exception1' 
    -o -wholename '/home/exception2' 
    -o -wholename '/home/exception3' \) 
    -prune -o 
    -wholename '*/public_html/outdated' -type d 
    -exec rm -rvf \{} \; 

Avant d'exécuter ce que je fortement suggère de remplacer le bit -exec rm -rvf \{} \; par -print pour vérifier qu'il n'imprime que ce que vous voulez supprimer.

Voici comment cela fonctionne: find trouve récursivement des choses. les choses dans \( ... \)' matches directories you want to skip entirely (ie: prune). The standard pattern for using -prune is to say what you want to prune out, then -prune -o`, et ensuite les choses que vous voulez réellement faire correspondre.

Nous voulons faire correspondre public_html/outdated répertoires, c'est ce que -wholename '*/public_html/outdated' -type d est pour. (-type d signifie "est un répertoire").

Enfin vient l'action que nous voulons effectuer. Une fois de plus, remplacez cette partie par -print jusqu'à ce que vous soyez sûr de faire ce que vous voulez.

Une mise en garde: Cela cracher un tas d'avertissements de la forme:

find: `/home/foo/public_html/outdated': No such file or directory 

C'est parce que trouver essaie de marcher dans ces répertoires juste supprimé. Vous pouvez les ignorer en toute sécurité - la recherche se poursuivra malgré les avertissements.

+0

Vous pouvez essayer d'utiliser '-execdir' au lieu de' -exec' avec '-depth' pour voir si cela élimine les messages d'erreur. –

+0

@Dennis Je n'avais pas essayé execdir, mais j'ai joué avec '-depth' en pensant que cela pourrait résoudre le problème (comme nous le ferions avec un sous-arbre au moment où nous l'avons supprimé). Cela a semblé complètement casser la taille, cependant, j'ai abandonné cette approche. –