Votre commande est d'abord analysée par le shell en deux commandes séparées par un ;, ce qui équivaut à une nouvelle ligne:
find . -name "*" -exec chgrp -v new_group {}
chmod -v 770 {} \;
Si vous voulez exécuter une commande shell, appelez explicitement un shell avec bash -c(ou sh -cpeu importe que le shell soit spécifiquement bash):
find . -name "*" -exec sh -c 'chgrp -v new_group "$0"; chmod -v 770 "$0"' {} \;
Notez l'utilisation de {}comme argument pour le shell; c'est l'argument zéro (qui est normalement le nom du shell ou du script, mais peu importe ici), et donc référencé par "$0".
Vous pouvez transmettre plusieurs noms de fichiers au shell à la fois et faire en sorte que celui-ci les parcoure, ce sera plus rapide. Ici, je passe _comme nom de script et les arguments suivants sont des noms de fichiers, qui for x(un raccourci pour for x in "$@") itèrent.
find . -name "*" -exec sh -c 'for x; do chgrp -v new_group "$x"; chmod -v 770 "$x"; done' _ {} +
Notez que depuis bash 4 ou en zsh, vous n'avez pas besoin de trouver du tout ici. Dans bash, exécutez shopt -s globstar(mettez-le dans votre ~/.bashrc) pour l'activer **/pour un répertoire glob récursif. (Dans zsh, cela est actif tout le temps.) Puis
chgrp -v new_group -- **/*; chmod -v 770 -- **/*
ou si vous voulez que les fichiers soient itérés dans l'ordre
for x in **/*; do
chgrp -v new_group -- "$x"
chmod -v 770 -- "$x"
done
Une différence avec la findcommande est que le shell ignore les fichiers de points (fichiers dont le nom commence par a .). Pour les inclure, dans bash, premier ensemble GLOBIGNORE=.:..; dans zsh, utilisez **/*(D)comme motif glob.
'{}'(apostrophes autour des accolades), rendez-