Você não precisa de nenhum dos GNUisms aqui (e provavelmente quer que um -mindepth 1
exclua .
), e você não precisa executar um chmod
por arquivo:
find . ! -name . -prune ! -type l -size +100c -size -1000c -print \
-exec chmod a+r {} + >testfile
(Eu também adicionei um ! -type l
porque -size
iria verificar o tamanho do link simbólico enquanto chmod
mudaria as permissões do alvo do symlink para que ele não faz sentido considerar os links simbólicos. É provável que você queira ir além e considerar apenas arquivos regulares ( -type f
))
Isso funciona aqui porque chmod
não produz nada em seu stdout (que de outra forma acabaria no testfile).
Mais geralmente, para evitar isso, você precisa fazer:
find . ! -name . -prune ! -type l -size +100c -size -1000c -print -exec sh -c '
exec cmd-that-may-write-to-stdout "$@" >&3 3>&-' sh {} + 3>&1 > testfile
Para que o stdout de find
vá para testfile
, mas o stdout de cmd-that-may-write-to-stdout
vai para o stdout original antes do redirecionamento (conforme salvo com 3>&1
acima).
Note que no seu:
find . -maxdepth 1 -size +100c -size -1000c -exec chmod a+r {} \; -print > testfile
testfile
conterá os arquivos para os quais chmod
foi bem-sucedida (o -print
sendo depois de -exec
significa -exec
é outra condição para esse -print
e -exec
terá êxito se o comando executado retornar com um status de saída diferente de zero).
Se você quisesse usar xargs
(aqui usando a sintaxe do GNU), você poderia usar tee
e processo de substituição:
find . ! -name . -prune ! -type l -size +100c -size -1000c -print0 |
tee >(tr '(<that-code>) 3>&1 | cat
' '\n' > testfile) |
xargs -r0 chmod a+r
Para salvar a saída de find
com NULs, transformou-se em novas linhas em testfile
. Observe, entretanto, que o comando tr
está sendo executado em segundo plano. Seu shell aguardará xargs
(pelo menos, a maioria dos shells também aguardará por tee
e find
), mas não por tr
. Portanto, há uma pequena chance de que tr
tenha terminado de gravar dados em testfile
quando o shell executar o próximo comando. Se for mais importante que o testfile
seja totalmente escrito até então que todas as permissões sejam modificadas, talvez você queira trocar os comandos xargs
e tr
acima.
Outra opção é envolver todo o código acima em:
files=(./*(L+100L-1000^@))
chmod a+r $files
print -rl $files > testfile
Dessa forma, o shell aguardará cat
e esse cat
sairá somente quando todos os processos que tiverem esse descritor de arquivo 3 abrirem na extremidade de gravação do canal que ele lê (incluindo tr
, find
, tee
, xargs
) foram encerrados.
Outra opção é usar zsh
globs aqui:
find . ! -name . -prune ! -type l -size +100c -size -1000c -print \
-exec chmod a+r {} + >testfile
Embora você possa encontrar erros muitos argumentos se a lista de arquivos for muito grande. find -exec +
e xargs
trabalham com isso executando vários comandos chmod
, se necessário. Você pode usar zargs
em zsh
para isso.