Ihr Befehl wird zuerst von der Shell in zwei durch ;ein Trennzeichen getrennte Befehle zerlegt, was einer neuen Zeile entspricht:
find . -name "*" -exec chgrp -v new_group {}
chmod -v 770 {} \;
Wenn Sie einen Shell-Befehl ausführen möchten, rufen Sie eine Shell explizit mit auf bash -c(oder sh -cwenn es Ihnen egal ist, dass die Shell speziell bash ist):
find . -name "*" -exec sh -c 'chgrp -v new_group "$0"; chmod -v 770 "$0"' {} \;
Beachten Sie die Verwendung von {}als Argument für die Shell. Es ist das nullte Argument (normalerweise der Name der Shell oder des Skripts, aber das spielt hier keine Rolle) "$0".
Sie können mehrere Dateinamen gleichzeitig an die Shell übergeben und die Shell durchlaufen lassen. Dies ist schneller. Hier übergebe ich _als Skriptnamen und die folgenden Argumente sind Dateinamen, über die for x(eine Abkürzung für for x in "$@") iteriert wird.
find . -name "*" -exec sh -c 'for x; do chgrp -v new_group "$x"; chmod -v 770 "$x"; done' _ {} +
Beachten Sie, dass Sie seit Bash 4 oder in zsh hier nichts mehr finden müssen. Führen shopt -s globstarSie in bash den Befehl aus (fügen Sie ihn in Ihren Ordner ein ~/.bashrc), um das **/Stehen für ein rekursives Verzeichnis glob zu aktivieren . (In zsh ist dies die ganze Zeit aktiv.) Dann
chgrp -v new_group -- **/*; chmod -v 770 -- **/*
oder wenn Sie möchten, dass die Dateien der Reihe nach durchlaufen werden
for x in **/*; do
chgrp -v new_group -- "$x"
chmod -v 770 -- "$x"
done
Ein Unterschied zum findBefehl besteht darin, dass die Shell Punktdateien (Dateien, deren Name mit a beginnt .) ignoriert . Um sie in die Bash aufzunehmen, setzen Sie zuerst GLOBIGNORE=.:..; Verwenden Sie in zsh **/*(D)als Glob-Muster.
'{}'(Apostrophe um die Klammern), besuchen Sie bitte: unix.stackexchange.com/q/8647/4485