Как написать сценарий оболочки, который запускает некоторые команды как суперпользователь, а некоторые не как суперпользователь, без необходимости присматривать за ним?

Я хочу написать сценарий оболочки для автоматизации ряда команд. Проблема в том, что некоторые команды ДОЛЖНЫ выполняться как суперпользователь, а некоторые команды НЕ ДОЛЖНЫ выполняться как суперпользователь То, что я сделал до сих пор, выглядит примерно так:

#!/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..)

Другие вопросы по тегам