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 -c
peu 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 find
commande 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-