Sur les systèmes qui le prennent en charge (GNU et quelques autres), vous pouvez faire:
sudo find /path/ -print0 | xargs -r0 process_paths
xargsn'est pas exécuté sous sudo, donc il a toujours les uids / gids d'origine et aussi l'environnement d'origine (au sens large), pas celui modifié par sudo.
process_pathsstdin finit cependant par être modifié (selon l' xargsimplémentation, il est ouvert sur /dev/nullou partage le pipefrom sudo/ find.
Pour éviter cela (avec GNU xargset des shells comme ksh, zshou bashqui prennent en charge la substitution de processus), vous pouvez faire:
xargs -r0a <(sudo find /path/ -print0) process_paths
Avec zsh:
sudo zsh -c '
files=(/path/**/*(D))
USERNAME=$SUDO_USER
autoload zargs
zargs $files -- process_paths'
Dans zsh, en attribuant un nom d'utilisateur à la $USERNAMEvariable spéciale, définissez les uids, gids sur celui de l'utilisateur correspondant dans la base de données utilisateur comme le sudo -u "$SUDO_USER"ferait.
Vous pourriez faire:
sudo sh -c '
exec find /path/ -exec sudo -u "$SUDO_USER" process_paths {} +'
Mais parce que sudotransmet une $SUDO_COMMANDvariable d'environnement (qui contient la concaténation des arguments avec des espaces) à process_paths, la liste des fichiers finit par être transmise deux fois, process_pathsce qui signifie que la limite de la taille maximale d'args + env est susceptible d'être atteinte s'il y a un grand nombre de fichiers.
Avec la plupart des suimplémentations, vous devriez pouvoir faire:
sudo sh -c '
exec find /path/ -exec su "$SUDO_USER" -c '\''
exec "$0" "$@"'\'' process_paths {} +'
mais comme sun'a pas le même problème.
... -exec sudo -u user process_paths {} \+