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.