У системах, які його підтримують (GNU та безліч інших), ви можете зробити:
sudo find /path/ -print0 | xargs -r0 process_paths
xargs
не запускається sudo
, тому в ньому все ще є оригінальні uids / gids, а також оригінальне середовище (у більшому сенсі), а не те, що модифіковане sudo
.
process_paths
stdin, в кінцевому підсумку, змінюється (залежно від xargs
реалізації, він відкритий на /dev/null
або ділиться pipe
з 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
спеціальній змінній, встановлюється uids, 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 {} \+