Trong lệnh `sudo find`, làm cách nào để đảm bảo lệnh` -exec` được chạy như người dùng bình thường?


10

Tôi đang cố gắng để làm cho lệnh sau hoạt động theo cách mà process_pathskịch bản không được chạy dưới các đặc quyền nâng cao. Có cách nào để làm việc này không?

sudo find /path/ -exec process_paths '{}' \+

Ở đây /path/có một số tệp không có quyền đọc cho người dùng bình thường. Kịch bản process_pathschỉ cần các đường dẫn.


... -exec sudo -u user process_paths {} \+
Satō Katsura

@SatoKatsura đôi khi điều này không thành công với sudo: unable to execute /usr/bin/perl: Argument list too long: /
pii_ke


2
Nếu bạn muốn các -execlệnh được gọi là người dùng của mình, tại sao bạn lại chạy findbằng cách sử dụng sudo?
marcelm

2
@marcelm Tôi nghĩ câu cuối cùng của câu hỏi trả lời của bạn.
Này

Câu trả lời:


16

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ự


1

Bạn có thể sử dụng sudo:

sudo find <directory> -exec sudo -u <normal_user> <command> {} \;

Nhưng như đã nói trong một nhận xét, rõ ràng nó có thể thất bại nếu {} quá dài cho sudo.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.