W systemach, które go obsługują (GNU i kilka innych), możesz:
sudo find /path/ -print0 | xargs -r0 process_paths
xargsnie jest uruchamiany pod sudo, więc nadal ma oryginalne identyfikatory / gids, a także oryginalne środowisko (w szerszym znaczeniu), a nie zmodyfikowane przez sudo.
process_pathsstdin zostaje jednak zmodyfikowany (w zależności od xargsimplementacji, jest otwarty /dev/nulllub udostępnia plik pipez sudo/ find.
Aby tego uniknąć (GNU xargsi muszli jak ksh, zshlub bashzastąpienie innych procesów wsparcia), można zrobić:
xargs -r0a <(sudo find /path/ -print0) process_paths
Z zsh:
sudo zsh -c '
files=(/path/**/*(D))
USERNAME=$SUDO_USER
autoload zargs
zargs $files -- process_paths'
W zsh, przypisując nazwę użytkownika do $USERNAMEspecjalnej zmiennej, ustawia identyfikatory użytkownika, identyfikatory użytkownika na odpowiadającego użytkownika w bazie danych użytkowników, tak jak sudo -u "$SUDO_USER"zrobiłby to.
Mógłbyś:
sudo sh -c '
exec find /path/ -exec sudo -u "$SUDO_USER" process_paths {} +'
Ponieważ jednak sudoprzekazuje $SUDO_COMMANDzmienną środowiskową (która zawiera konkatenację argumentów ze spacjami) process_paths, lista plików jest przekazywana dwukrotnie, process_pathsco oznacza, że limit maksymalnej wielkości argumentów + env zostanie prawdopodobnie osiągnięty, jeśli istnieje duża liczba plików.
W przypadku większości suimplementacji powinieneś być w stanie:
sudo sh -c '
exec find /path/ -exec su "$SUDO_USER" -c '\''
exec "$0" "$@"'\'' process_paths {} +'
chociaż sunie ma tego samego problemu.
... -exec sudo -u user process_paths {} \+