Sur les systèmes qui le prennent en charge (GNU et quelques autres), vous pouvez faire:
sudo find /path/ -print0 | xargs -r0 process_paths
xargs
n'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_paths
stdin finit cependant par être modifié (selon l' xargs
implémentation, il est ouvert sur /dev/null
ou partage le pipe
from sudo
/ find
.
Pour éviter cela (avec GNU xargs
et des shells comme ksh
, zsh
ou bash
qui 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 $USERNAME
variable 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 sudo
transmet une $SUDO_COMMAND
variable 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_paths
ce 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 su
implémentations, vous devriez pouvoir faire:
sudo sh -c '
exec find /path/ -exec su "$SUDO_USER" -c '\''
exec "$0" "$@"'\'' process_paths {} +'
mais comme su
n'a pas le même problème.
... -exec sudo -u user process_paths {} \+