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

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

#!/bin/bash

command1
sudo command2
command3
sudo command4

Проблема в том, что это означает, что кто-то должен дождаться завершения команды 1, прежде чем им будет предложено ввести пароль, тогда, если команда 3 займет достаточно много времени, им придется ждать завершения команды3. Было бы хорошо, если бы человек мог встать и уйти, а потом вернуться через час и сделать это. Например, следующая проблема script:

#!/bin/bash

sleep 310
sudo echo "Hi, I'm root"
sleep 310
sudo echo "I'm still root?"

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

Update:

Спасибо за ответы. Я бегу на Mac OS X Lion и побежал Stephen P script и получил разные результаты: (Я также добавил $HOME)

[email protected] scratch$ ./test2.sh
uid is 501
user is pair
username is 
home directory is /Users/pair
[email protected] scratch$ sudo ./test2.sh 
Password:
uid is 0
user is root
username is root
home directory is /Users/pair

Ответ 1

Файл 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.

Просто позвоните, чтобы вызвать ваш script, в первую очередь, он будет запрашивать пароль один раз.


Я изначально написал этот ответ на Linux, который имеет некоторые отличия от OS X

OS X (я тестирую это на Mountain Lion 10.8.3) имеет переменную окружения SUDO_USER, когда вы используете sudo, которую можно использовать вместо USERNAME выше, или быть более сложным, платформа script может проверить, установлен ли SUDO_USER и использовать ее, если это так, или использовать USERNAME, если это установлено.

Изменив исходный script для 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 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 "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.

Ответ 2

Вы должны запустить весь script как суперпользователь. Если вы хотите запустить некоторую команду как не-суперпользователь, используйте опцию -u для sudo:

#!/bin/bash

sudo -u username command1
command2
sudo -u username command3
command4

При запуске от имени пользователя root sudo не запрашивает пароль.

Ответ 3

Если вы используете это, проверьте man sudo тоже:

#!/bin/bash

sudo echo "Hi, I'm root"

sudo -u nobody echo "I'm nobody"

sudo -u 1000 touch /test_user

Ответ 4

Ну, у вас есть несколько вариантов.

Вы можете настроить sudo, чтобы не запрашивать пароль. Это не рекомендуется из-за рисков безопасности.

Вы можете написать ожидание script, чтобы прочитать пароль и предоставить его sudo, когда это необходимо, но это неудобно и хрупко.

Я бы рекомендовал создать script для запуска от имени root и отказаться от его привилегий, когда они не нужны. Просто имейте sudo -u someotheruser command для команд, для которых не требуется root.

(Если они должны запускаться специально как пользователь, вызывающий script, то вы можете иметь script сохранить uid и вызывать второй script через sudo с идентификатором в качестве аргумента, поэтому он знает, кто to su to..)