Twoje polecenie jest najpierw analizowane przez powłokę na dwa polecenia oddzielone znakiem a ;
, co jest równoważne nowej linii:
find . -name "*" -exec chgrp -v new_group {}
chmod -v 770 {} \;
Jeśli chcesz uruchomić polecenie powłoki, jawnie wywołaj powłokę za pomocą bash -c
(lub sh -c
jeśli nie obchodzi cię, że powłoka jest specjalnie bash):
find . -name "*" -exec sh -c 'chgrp -v new_group "$0"; chmod -v 770 "$0"' {} \;
Zwróć uwagę na użycie {}
jako argumentu dla powłoki; jest to zerowy argument (który zwykle jest nazwą powłoki lub skryptu, ale nie ma to tutaj znaczenia), stąd też nazywany "$0"
.
Możesz przekazać wiele nazw plików do powłoki jednocześnie i sprawić, że powłoka będzie się przez nie iterować, będzie to szybsze. Podaję tutaj _
jako nazwę skryptu, a następujące argumenty to nazwy plików, które for x
(skrót do for x in "$@"
) iterują.
find . -name "*" -exec sh -c 'for x; do chgrp -v new_group "$x"; chmod -v 770 "$x"; done' _ {} +
Zauważ, że odkąd bash 4 lub w zsh, tutaj wcale nie musisz go znaleźć. W bash, uruchom shopt -s globstar
(włóż to do swojego ~/.bashrc
), aby aktywować tryb **/
stojący dla globalnego katalogu rekurencyjnego. (W Zsh jest to aktywne przez cały czas.) Następnie
chgrp -v new_group -- **/*; chmod -v 770 -- **/*
lub jeśli chcesz, aby pliki były iterowane w kolejności
for x in **/*; do
chgrp -v new_group -- "$x"
chmod -v 770 -- "$x"
done
Jedną różnicą w stosunku do find
polecenia jest to, że powłoka ignoruje pliki kropkowe (pliki, których nazwa zaczyna się od a .
). Aby je uwzględnić, w bash, pierwszy zestaw GLOBIGNORE=.:..
; w zsh użyj **/*(D)
jako wzorca globu.
'{}'
(apostrofy wokół nawiasów klamrowych), odwiedź: unix.stackexchange.com/q/8647/4485