У команді `sudo find` як я можу переконатися, що команда` -exec` виконується як звичайний користувач?


10

Я намагаюся змусити наступну команду працювати так, щоб process_pathsсценарій не запускався з підвищеними привілеями. Чи є спосіб це зробити?

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

Тут /path/є деякі файли, які не мають дозволу на читання для звичайного користувача. Сценарій process_pathsпросто потребує шляхів.


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

@SatoKatsura інколи це не вдається sudo: unable to execute /usr/bin/perl: Argument list too long: /
pii_ke

1
Так, дивіться примітку про SUDO_COMMANDзмінну у пошуку. . [^.] * -тип f -принт0 | xargs -0 sudo chmod 664; не працює
Stéphane Chazelas

2
Якщо ви хочете, щоб -execкоманди були викликані вашим користувачем, чому ви в першу чергу findвикористовуєте використання sudo?
marcelm

2
@marcelm Я думаю, що останнє речення питання відповідає вашому.
Гей,

Відповіді:


16

У системах, які його підтримують (GNU та безліч інших), ви можете зробити:

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

xargsне запускається sudo, тому в ньому все ще є оригінальні uids / gids, а також оригінальне середовище (у більшому сенсі), а не те, що модифіковане sudo.

process_pathsstdin, в кінцевому підсумку, змінюється (залежно від xargsреалізації, він відкритий на /dev/nullабо ділиться pipeз sudo/ find.

Щоб уникнути цього (з GNU xargsі черепашок , як ksh, zshабо bashщо заміна процесу підтримки), ви можете зробити:

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

З zsh:

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

У цьому випадку zsh, присвоюючи ім'я користувача $USERNAMEспеціальній змінній, встановлюється uids, gids до відповідного користувача в базі даних користувачів, як це sudo -u "$SUDO_USER"було б.

Ви можете зробити:

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

Але оскільки sudoпередається $SUDO_COMMANDзмінна середовища (яка містить конкатенацію аргументів з пробілами) до process_paths, список файлів в кінцевому підсумку передається двічі, process_pathsщо означає, що обмеження на максимальний розмір args + env, ймовірно, буде досягнуто, якщо є великий кількість файлів.

У більшості suреалізацій ви повинні:

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

хоча як suне має тієї ж проблеми.


1

Ви можете використовувати sudo:

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

Але, як сказано в коментарі, це, мабуть, може зазнати невдачі, якщо {} занадто довгий для судо.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.