W systemach, które go obsługują (GNU i kilka innych), możesz:
sudo find /path/ -print0 | xargs -r0 process_paths
xargs
nie jest uruchamiany pod sudo
, więc nadal ma oryginalne identyfikatory / gids, a także oryginalne środowisko (w szerszym znaczeniu), a nie zmodyfikowane przez sudo
.
process_paths
stdin zostaje jednak zmodyfikowany (w zależności od xargs
implementacji, jest otwarty /dev/null
lub udostępnia plik pipe
z sudo
/ find
.
Aby tego uniknąć (GNU xargs
i muszli jak ksh
, zsh
lub bash
zastąpienie innych procesów wsparcia), można zrobić:
xargs -r0a <(sudo find /path/ -print0) process_paths
Z zsh
:
sudo zsh -c '
files=(/path/**/*(D))
USERNAME=$SUDO_USER
autoload zargs
zargs $files -- process_paths'
W zsh
, przypisując nazwę użytkownika do $USERNAME
specjalnej zmiennej, ustawia identyfikatory użytkownika, identyfikatory użytkownika na odpowiadającego użytkownika w bazie danych użytkowników, tak jak sudo -u "$SUDO_USER"
zrobiłby to.
Mógłbyś:
sudo sh -c '
exec find /path/ -exec sudo -u "$SUDO_USER" process_paths {} +'
Ponieważ jednak sudo
przekazuje $SUDO_COMMAND
zmienną środowiskową (która zawiera konkatenację argumentów ze spacjami) process_paths
, lista plików jest przekazywana dwukrotnie, process_paths
co oznacza, że limit maksymalnej wielkości argumentów + env zostanie prawdopodobnie osiągnięty, jeśli istnieje duża liczba plików.
W przypadku większości su
implementacji powinieneś być w stanie:
sudo sh -c '
exec find /path/ -exec su "$SUDO_USER" -c '\''
exec "$0" "$@"'\'' process_paths {} +'
chociaż su
nie ma tego samego problemu.
... -exec sudo -u user process_paths {} \+