На системах, которые его поддерживают (GNU и многие другие), вы можете сделать:
sudo find /path/ -print0 | xargs -r0 process_paths
xargs
не запускается sudo
, поэтому он все еще имеет исходные uids / gids, а также исходную среду (в более широком смысле), а не ту, которая была изменена sudo
.
process_paths
Тем не менее, stdin изменяется (в зависимости от xargs
реализации он открыт /dev/null
или разделяет pipe
from sudo
/ find
.
Чтобы избежать этого (с GNU xargs
и ракушек , как ksh
, zsh
или bash
что замена процесса поддержки), вы можете сделать:
xargs -r0a <(sudo find /path/ -print0) process_paths
С zsh
:
sudo zsh -c '
files=(/path/**/*(D))
USERNAME=$SUDO_USER
autoload zargs
zargs $files -- process_paths'
В zsh
, назначая имя пользователя $USERNAME
специальной переменной, устанавливает идентификаторы uid и gids для соответствующего пользователя в базе данных пользователей, как sudo -u "$SUDO_USER"
было бы.
Вы могли бы сделать:
sudo sh -c '
exec find /path/ -exec sudo -u "$SUDO_USER" process_paths {} +'
Но поскольку sudo
передает $SUDO_COMMAND
переменную среды (которая содержит конкатенацию аргументов с пробелами) в process_paths
, список файлов заканчивается передачей дважды, process_paths
что означает, что ограничение максимального размера args + env, вероятно, будет достигнуто, если имеется большой количество файлов.
С большинством su
реализаций вы должны быть в состоянии сделать:
sudo sh -c '
exec find /path/ -exec su "$SUDO_USER" -c '\''
exec "$0" "$@"'\'' process_paths {} +'
хотя, поскольку su
не имеет такой же проблемы.
... -exec sudo -u user process_paths {} \+