Seu comando é primeiro analisado pelo shell em dois comandos separados por a ;
, o que é equivalente a uma nova linha:
find . -name "*" -exec chgrp -v new_group {}
chmod -v 770 {} \;
Se você deseja executar um comando do shell, chame um shell explicitamente com bash -c
(ou sh -c
se você não se importa que o shell seja especificamente do bash):
find . -name "*" -exec sh -c 'chgrp -v new_group "$0"; chmod -v 770 "$0"' {} \;
Observe o uso de {}
como um argumento para o shell; é o argumento zeroth (que normalmente é o nome do shell ou script, mas isso não importa aqui), portanto referido como "$0"
.
Você pode passar vários nomes de arquivos para o shell de cada vez e fazer com que o shell itere através deles, será mais rápido. Aqui passo _
como o nome do script e os argumentos a seguir são nomes de arquivos, que for x
(um atalho para for x in "$@"
) iteram.
find . -name "*" -exec sh -c 'for x; do chgrp -v new_group "$x"; chmod -v 770 "$x"; done' _ {} +
Observe que desde o bash 4, ou no zsh, você não precisa encontrar nada aqui. No bash, execute shopt -s globstar
(coloque-o no seu ~/.bashrc
) para ativar a **/
posição de um diretório recursivo glob. (No zsh, isso fica ativo o tempo todo.)
chgrp -v new_group -- **/*; chmod -v 770 -- **/*
ou se você deseja que os arquivos sejam iterados em ordem
for x in **/*; do
chgrp -v new_group -- "$x"
chmod -v 770 -- "$x"
done
Uma diferença com o find
comando é que o shell ignora arquivos de ponto (arquivos cujo nome começa com a .
). Para incluí-los, no bash, primeiro conjunto GLOBIGNORE=.:..
; no zsh, use **/*(D)
como padrão glob.
'{}'
(apóstrofos ao redor do aparelho), visite: unix.stackexchange.com/q/8647/4485