В команде `sudo find`, как мне убедиться, что команда` -exec` запущена от имени обычного пользователя?

10

Я пытаюсь заставить следующую команду работать так, чтобы process_pathsскрипт не выполнялся с повышенными привилегиями. Есть ли способ сделать это?

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

Здесь /path/есть некоторые файлы, которые не имеют разрешения на чтение для обычного пользователя. Скрипту process_pathsнужны только пути.

pii_ke
источник
... -exec sudo -u user process_paths {} \+
Satō
@SatoKatsura иногда это терпит неудачу с sudo: unable to execute /usr/bin/perl: Argument list too long: /
pii_ke
1
Да, см. Примечание о SUDO_COMMANDпеременной в find. . [^.] * -типа f -print0 | xargs -0 sudo chmod 664; не работает
Стефан Шазелас
2
Если вы хотите , чтобы -execкоманды , которые будут вызываться в качестве пользователя, почему вы работаете , findиспользуя sudoв первую очередь?
marcelm
2
@ marcelm Я думаю, что последнее предложение вопроса отвечает твоему.
Привет,

Ответы:

16

На системах, которые его поддерживают (GNU и многие другие), вы можете сделать:

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

xargsне запускается sudo, поэтому он все еще имеет исходные uids / gids, а также исходную среду (в более широком смысле), а не ту, которая была изменена sudo.

process_pathsТем не менее, stdin изменяется (в зависимости от xargsреализации он открыт /dev/nullили разделяет pipefrom 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специальной переменной, устанавливает идентификаторы uid и 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> {} \;

Но, как сказано в комментарии, он может потерпеть неудачу, если {} слишком длинный для sudo.

Привет
источник