Em sistemas que o suportam (GNU e muitos outros), você pode:
sudo find /path/ -print0 | xargs -r0 process_paths
xargsnão é executado abaixo sudo, por isso ainda possui os uids / gids originais e também o ambiente original (no sentido mais amplo), não o modificado por sudo.
process_pathsstdin acaba sendo modificado embora (dependendo da xargsaplicação, é aberto sobre /dev/nullou ações pipede sudo/ find.
Para evitar isso (com GNU xargse shells como ksh, zshou bashque suportam a substituição de processos), você pode:
xargs -r0a <(sudo find /path/ -print0) process_paths
Com zsh:
sudo zsh -c '
files=(/path/**/*(D))
USERNAME=$SUDO_USER
autoload zargs
zargs $files -- process_paths'
Em zsh, atribuindo um nome de usuário à $USERNAMEvariável especial, define os uids, gids como os do usuário correspondente no banco de dados do usuário, como sudo -u "$SUDO_USER"faria.
Você poderia fazer:
sudo sh -c '
exec find /path/ -exec sudo -u "$SUDO_USER" process_paths {} +'
Mas como sudopassa uma $SUDO_COMMANDvariável de ambiente (que contém a concatenação dos argumentos com espaços) para process_paths, a lista de arquivos acaba sendo passada duas vezes, o process_pathsque significa que o limite no tamanho máximo de args + env será atingido se houver um grande número de arquivos.
Com a maioria das suimplementações, você deve ser capaz de:
sudo sh -c '
exec find /path/ -exec su "$SUDO_USER" -c '\''
exec "$0" "$@"'\'' process_paths {} +'
embora sunão tenha o mesmo problema.
... -exec sudo -u user process_paths {} \+