Следующее относится к случаю, когда вы хотите выполнить команду без пароля, только если она имеет определенный набор параметров, где часть параметров является переменной . AFAIK невозможно использовать переменные или диапазоны значений в объявлениях sudoers, т.е. вы можете явно разрешить доступ, command option1но не command option2используя:
user_name ALL=(root) /usr/bin/command option1
но если структура command option1 value1, где value1могут варьироваться, вам нужно будет иметь явную sudoers линию для каждого возможного значения value1. Сценарий оболочки предоставляет способ обойти это.
Этот ответ был вдохновлен ответом Ахмада Зафара и устраняет проблему безопасности.
- Создайте сценарий оболочки, в котором вы вызываете команду без
sudo.
- Сохраните сценарий в папке с правами суперпользователя (например
/usr/local/bin/), сделайте файл корневым (например chown root:wheel /usr/local/bin/script_name) без прав на запись для других (например chmod 755 /usr/local/bin/script_name).
Добавьте исключение для sudoers, используя visudo:
user_name ALL=(root) NOPASSWD: /usr/local/bin/script_name,
Запустите ваш скрипт sudo script_name.
Например, я хочу изменить время ожидания для отображения в macOS. Это делается с помощью:
sudo pmset displaysleep time_in_minutes
Я считаю изменение тайм-аута невинным действием, которое не оправдывает хлопот при наборе пароля, но pmsetможет многое, и я бы хотел оставить эти другие вещи за паролем sudo.
Итак, у меня есть следующий скрипт /usr/local/bin/ds:
#!/bin/bash
if [ $# -eq 0 ]; then
echo 'To set displaysleep time, run "sudo ds [sleep_time_in_minutes]"'
else
if [[ $1 =~ ^([0-9]|[1-9][0-9]|1[0-7][0-9]|180)$ ]]; then
pmset displaysleep $1
else
echo 'Time must be 0..180, where 0 = never, 1..180 = number of minutes'
fi
fi
В конце sudoersфайла у меня есть следующая строка:
user_name ALL=(root) NOPASSWD: /usr/local/bin/ds
Чтобы установить тайм-аут на 3 минуты, я запускаю свой скрипт из учетной записи обычного пользователя user_name:
sudo ds 3
PS Большая часть моего сценария является проверкой ввода, которая не является обязательной, поэтому также будет работать следующее:
#!/bin/bash
pmset displaysleep $1
/path/to/my/programбыл сценарий Python?