Dalam perintah `sudo find`, bagaimana cara memastikan bahwa perintah` -exec` dijalankan sebagai pengguna normal?

10

Saya mencoba membuat perintah berikut berfungsi dengan cara agar process_pathsskrip tidak dijalankan di bawah hak istimewa yang ditinggikan. Apakah ada cara untuk melakukan ini?

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

Di sini /path/ada beberapa file yang tidak memiliki izin baca untuk pengguna normal. Script process_pathshanya membutuhkan path.

pii_ke
sumber
... -exec sudo -u user process_paths {} \+
Satō Katsura
@SatoKatsura terkadang gagal dengan sudo: unable to execute /usr/bin/perl: Argument list too long: /
pii_ke
1
Ya, lihat catatan tentang SUDO_COMMANDvariabel dalam find. . [^.] * -type f -print0 | xargs -0 sudo chmod 664; tidak bekerja
Stéphane Chazelas
2
Jika Anda ingin -execperintah dipanggil sebagai pengguna Anda, mengapa Anda menjalankan findmenggunakan sudodi tempat pertama?
marcelm
2
@marcelm Saya pikir kalimat terakhir dari pertanyaan menjawab pertanyaan Anda.
Hei

Jawaban:

16

Pada sistem yang mendukungnya (GNU dan beberapa lainnya), Anda dapat melakukan:

sudo find /path/ -print0 | xargs -r0 process_paths

xargstidak berjalan di bawah sudo, sehingga masih memiliki uids / gids asli dan juga lingkungan asli (dalam arti yang lebih besar), bukan yang dimodifikasi oleh sudo.

process_pathsstdin akhirnya dimodifikasi (tergantung pada xargsimplementasinya, terbuka /dev/nullatau berbagi pipedari sudo/ find.

Untuk menghindarinya (dengan GNU xargsdan shells like ksh, zshatau bashsubstitusi proses dukungan), Anda dapat melakukan:

xargs -r0a <(sudo find /path/ -print0) process_paths

Dengan zsh:

sudo zsh -c '
   files=(/path/**/*(D))
   USERNAME=$SUDO_USER
   autoload zargs
   zargs $files -- process_paths'

Di zsh, menugaskan nama pengguna ke $USERNAMEvariabel khusus, mengatur uids, gids ke pengguna yang sesuai dalam database pengguna seperti yang sudo -u "$SUDO_USER"akan dilakukan.

Anda bisa melakukannya:

 sudo sh -c '
   exec find /path/ -exec sudo -u "$SUDO_USER" process_paths {} +'

Tetapi karena sudomelewati $SUDO_COMMANDvariabel lingkungan (yang berisi rangkaian argumen dengan spasi) ke process_paths, daftar file akhirnya diteruskan dua kali process_pathsyang berarti batas pada ukuran maksimum args + env kemungkinan akan tercapai jika ada besar jumlah file.

Dengan sebagian besar suimplementasi, Anda harus dapat melakukan:

 sudo sh -c '
   exec find /path/ -exec su "$SUDO_USER" -c '\''
     exec "$0" "$@"'\'' process_paths {} +'

meskipun karena sutidak memiliki masalah yang sama.

Stéphane Chazelas
sumber
1

Anda bisa menggunakan sudo:

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

Tetapi seperti yang dikatakan dalam komentar, itu bisa gagal jika {} terlalu panjang untuk sudo.

Hei
sumber