Trên các hệ thống hỗ trợ nó (GNU và khá nhiều hệ thống khác), bạn có thể làm:
sudo find /path/ -print0 | xargs -r0 process_paths
xargs
không được chạy bên dưới sudo
, vì vậy nó vẫn có các uids / gids ban đầu và cả môi trường ban đầu (theo nghĩa lớn hơn), không phải là cái được sửa đổi bởi sudo
.
process_paths
stdin cuối cùng đã được sửa đổi (tùy thuộc vào việc xargs
thực hiện, nó mở /dev/null
hoặc chia sẻ pipe
từ sudo
/ find
.
Để tránh điều đó (với GNU xargs
và vỏ như ksh
, zsh
hoặc bash
rằng quá trình hỗ trợ thay thế), bạn có thể làm:
xargs -r0a <(sudo find /path/ -print0) process_paths
Với zsh
:
sudo zsh -c '
files=(/path/**/*(D))
USERNAME=$SUDO_USER
autoload zargs
zargs $files -- process_paths'
Trong zsh
, việc gán tên người dùng cho $USERNAME
biến đặc biệt, đặt các uids, gids thành tên của người dùng tương ứng trong cơ sở dữ liệu người dùng như sudo -u "$SUDO_USER"
sẽ làm.
Bạn có thể làm:
sudo sh -c '
exec find /path/ -exec sudo -u "$SUDO_USER" process_paths {} +'
Nhưng vì sudo
chuyển một $SUDO_COMMAND
biến môi trường (chứa kết hợp các đối số có khoảng trắng) process_paths
, nên danh sách các tệp cuối cùng được truyền hai lần process_paths
, có nghĩa là giới hạn về kích thước tối đa của args + env có thể đạt được nếu có lớn số lượng tập tin.
Với hầu hết các su
triển khai, bạn sẽ có thể làm:
sudo sh -c '
exec find /path/ -exec su "$SUDO_USER" -c '\''
exec "$0" "$@"'\'' process_paths {} +'
mặc dù su
không có vấn đề tương tự
... -exec sudo -u user process_paths {} \+