Как написать сценарий оболочки, который запускает некоторые команды как суперпользователь, а некоторые не как суперпользователь, без необходимости присматривать за ним?
Я хочу написать сценарий оболочки для автоматизации ряда команд. Проблема в том, что некоторые команды ДОЛЖНЫ выполняться как суперпользователь, а некоторые команды НЕ ДОЛЖНЫ выполняться как суперпользователь То, что я сделал до сих пор, выглядит примерно так:
#!/bin/bash
command1
sudo command2
command3
sudo command4
Проблема в том, что это означает, что кто-то должен дождаться завершения команды 1, прежде чем ему будет предложено ввести пароль, а затем, если команда 3 займет достаточно много времени, ему придется ждать завершения команды 3. Было бы неплохо, если бы человек мог встать и уйти, а затем вернуться через час и закончить. Например, следующий скрипт имеет эту проблему:
#!/bin/bash
sleep 310
sudo echo "Hi, I'm root"
sleep 310
sudo echo "I'm still root?"
Как я могу сделать так, чтобы пользователь мог просто ввести свой пароль один раз, в самом начале, а затем уйти?
Обновить:
Спасибо за ответы. Я работаю на Mac OS X Lion, запустил скрипт Стивена П и получил другие результаты: (Я также добавил $HOME)
pair@abbey scratch$ ./test2.sh
uid is 501
user is pair
username is
home directory is /Users/pair
pair@abbey scratch$ sudo ./test2.sh
Password:
uid is 0
user is root
username is root
home directory is /Users/pair
4 ответа
Файл sutest
#!/bin/bash
echo "uid is ${UID}"
echo "user is ${USER}"
echo "username is ${USERNAME}"
запустите его: `./sutest'дает мне
uid is 500
user is stephenp
username is stephenp
но используя sudo: sudo ./sutest
дает
uid is 0
user is root
username is stephenp
Таким образом, вы сохраняете исходное имя пользователя в $USERNAME при запуске от имени sudo. Это приводит к решению, аналогичному тому, что опубликовали другие:
#!/bin/bash
sudo -u ${USERNAME} normal_command_1
root_command_1
root_command_2
sudo -u ${USERNAME} normal_command_2
# etc.
Просто sudo для запуска вашего скрипта в первую очередь, он запросит пароль один раз.
Я первоначально написал этот ответ на Linux, который имеет некоторые различия с OS X
OS X (я тестирую это на Mountain Lion 10.8.3) имеет переменную окружения SUDO_USER
когда вы запускаете sudo, который можно использовать вместо USERNAME
выше, или, чтобы быть более кросс-платформенным, скрипт может проверить, установлен ли SUDO_USER, и использовать его, если так, или использовать USERNAME, если он установлен.
Меняя оригинальный скрипт для OS X, он становится...
#!/bin/bash
sudo -u ${SUDO_USER} normal_command_1
root_command_1
root_command_2
sudo -u ${SUDO_USER} normal_command_2
# etc.
Первый удар по созданию кроссплатформенности может быть...
#!/bin/bash
#
# set "THE_USER" to SUDO_USER if that's set,
# else set it to USERNAME if THAT is set,
# else set it to the string "unknown"
# should probably then test to see if it's "unknown"
#
THE_USER=${SUDO_USER:-${USERNAME:-unknown}}
sudo -u ${THE_USER} normal_command_1
root_command_1
root_command_2
sudo -u ${THE_USER} normal_command_2
# etc.
Вы должны запустить весь ваш скрипт как суперпользователь. Если вы хотите запустить какую-то команду как не суперпользователь, используйте параметр -u команды sudo:
#!/bin/bash
sudo -u username command1
command2
sudo -u username command3
command4
При запуске от имени root sudo не запрашивает пароль.
Если вы используете это, проверьте man sudo
тоже:
#!/bin/bash
sudo echo "Hi, I'm root"
sudo -u nobody echo "I'm nobody"
sudo -u 1000 touch /test_user
Ну, у вас есть несколько вариантов.
Вы можете настроить sudo, чтобы не запрашивать пароль. Это не рекомендуется из-за угроз безопасности.
Вы можете написать ожидаемый скрипт для чтения пароля и предоставления его sudo, когда это необходимо, но это неуклюже и хрупко.
Я бы порекомендовал разработать скрипт для запуска с правами root и отбросить его привилегии, когда они не нужны. Просто имейте это sudo -u someotheruser command
для команд, которые не требуют root.
(Если они должны запускаться именно как пользователь, вызывающий скрипт, то вы можете попросить скрипт сохранить uid и вызвать второй скрипт через sudo с идентификатором в качестве аргумента, чтобы он знал, кому нужно su..)