Sui sistemi che lo supportano (GNU e molti altri), potresti fare:
sudo find /path/ -print0 | xargs -r0 process_paths
xargs
non viene eseguito sudo
, quindi ha ancora gli uid / gids originali e anche l'ambiente originale (in senso lato), non quello modificato da sudo
.
process_paths
stdin finisce per essere modificato (a seconda xargs
dell'implementazione, è aperto /dev/null
o condivide il pipe
da sudo
/ find
.
Per evitarlo (con GNU xargs
e shell simili ksh
, zsh
o bash
che supportano la sostituzione del processo), potresti fare:
xargs -r0a <(sudo find /path/ -print0) process_paths
Con zsh
:
sudo zsh -c '
files=(/path/**/*(D))
USERNAME=$SUDO_USER
autoload zargs
zargs $files -- process_paths'
In zsh
, assegnando un nome utente alla $USERNAME
variabile speciale, imposta gli uid, i gids a quello dell'utente corrispondente nel database degli utenti come sudo -u "$SUDO_USER"
farebbe.
Potresti fare:
sudo sh -c '
exec find /path/ -exec sudo -u "$SUDO_USER" process_paths {} +'
Ma poiché sudo
passa una $SUDO_COMMAND
variabile di ambiente (che contiene la concatenazione degli argomenti con spazi) a process_paths
, l'elenco dei file finisce per essere passato due volte, il process_paths
che significa che è possibile raggiungere il limite sulla dimensione massima di args + env se c'è un grande numero di file.
Con la maggior parte delle su
implementazioni, dovresti essere in grado di fare:
sudo sh -c '
exec find /path/ -exec su "$SUDO_USER" -c '\''
exec "$0" "$@"'\'' process_paths {} +'
sebbene su
non abbia lo stesso problema.
... -exec sudo -u user process_paths {} \+