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
xargskhô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_pathsstdin cuối cùng đã được sửa đổi (tùy thuộc vào việc xargsthực hiện, nó mở /dev/nullhoặc chia sẻ pipetừ sudo/ find.
Để tránh điều đó (với GNU xargsvà vỏ như ksh, zshhoặc bashrằ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 $USERNAMEbiế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ì sudochuyển một $SUDO_COMMANDbiế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 sutriể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ù sukhông có vấn đề tương tự
... -exec sudo -u user process_paths {} \+