En los sistemas que lo admiten (GNU y muchos otros), puede hacer lo siguiente:
sudo find /path/ -print0 | xargs -r0 process_paths
xargs
no se ejecuta debajo sudo
, por lo que todavía tiene los uids / gids originales y también el entorno original (en el sentido más amplio), no el modificado por sudo
.
process_paths
sin embargo, stdin termina siendo modificado (dependiendo de la xargs
implementación, está abierto /dev/null
o comparte pipe
desde sudo
/ find
.
Para evitar eso (con GNU xargs
y shells como ksh
, zsh
o bash
que admitan la sustitución del proceso), puede hacer lo siguiente:
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'
En zsh
, la asignación de un nombre de usuario a la $USERNAME
variable especial, establece los uids, gids a los del usuario correspondiente en la base de datos de usuarios como sudo -u "$SUDO_USER"
lo haría.
Podrías hacerlo:
sudo sh -c '
exec find /path/ -exec sudo -u "$SUDO_USER" process_paths {} +'
Pero debido a que sudo
pasa una $SUDO_COMMAND
variable de entorno (que contiene la concatenación de los argumentos con espacios) a process_paths
, la lista de archivos termina pasándose dos veces, lo process_paths
que significa que es probable que se alcance el límite del tamaño máximo de args + env si hay un gran Número de archivos.
Con la mayoría de las su
implementaciones, debería poder hacer:
sudo sh -c '
exec find /path/ -exec su "$SUDO_USER" -c '\''
exec "$0" "$@"'\'' process_paths {} +'
aunque como su
no tiene el mismo problema.
... -exec sudo -u user process_paths {} \+