sudo в неинтерактивном скрипте

9

У меня есть скрипт , который выполняет три функции: A && B && C.

Функцию Bнужно запускать как суперпользователь, Aа Cпока нет.

У меня есть несколько решений, но ни одно из них не удовлетворяет:

  1. sudo весь скрипт: sudo 'A && B && C'

    Это кажется плохой идеей для запуска Aи Cкак супер-пользователь, если он не нужен

  2. сделать скрипт интерактивным: A && sudo B && C

    Возможно, мне придется ввести свой пароль, но я хочу, чтобы мой сценарий был неинтерактивным, поскольку каждая функция может занять некоторое время, и я не хочу, чтобы сценарий ждал меня. Ну, это также, почему это сценарий, так что мне не нужно смотреть его запуск.

  3. Глупое решение: sudo : && A && sudo -n B && C

    Сначала кажется глупым запускать неоперативный код sudo, а также я должен скрестить палец, что А не собирается брать больше, чем $sudo_timeout.

  4. Гипотетическое решение (я хочу, чтобы вы сказали, что оно существует):

    sudo --store-cred 'A && sudo --use-cred-from-parent-sudo B && C'

    Это будет запрашивать мой пароль в начале, а затем использовать эти учетные данные только при необходимости.

Что ты думаешь обо всем этом? Я был бы очень удивлен, что нет решения этой проблемы, так как я думаю, что это довольно распространенная проблема (как насчет make all && sudo make install)

Антуан Пелисс
источник
3
Вы можете сделать скрипт , который будет выполняться с Судом, но в сценарии выполните Aи Cчасти явного использования su -l some_non_priviliged_user. Нет проблем с тайм-аутом и нет привилегий для A и C. Я не думаю, что 4 возможно, sudoкажется "глобальным состоянием" для пользователя.
Anthon

Ответы:

7

Я думаю, что лучшее, что вы можете сделать, это запустить скрипт, sudoа затем запустить процессы, которые вы хотите запустить как обычный пользователь, явно с помощью su userили sudo -u user:

#!/usr/bin/env bash

## Detect the user who launched the script
usr=$(env | grep SUDO_USER | cut -d= -f 2)

## Exit if the script was not launched by root or through sudo
if [ -z $usr ] && [ $USER = "root" ]
then
    echo "The script needs to run as root" && exit 1
fi

## Run the job(s) that don't need root
sudo -u $usr commandA

## Run the job that needs to be run as root
commandB
Тердон
источник
9

Добавьте ваш скрипт в /etc/sudoersфайл с NOPASSWDатрибутом, чтобы он мог запускаться без запроса пароля. Вы можете привязать это к определенному пользователю (или группе пользователей) или разрешить запускать sudoего любому пользователю вашей системы.

Пример строки для скрипта с именем /usr/local/bin/bossyможет выглядеть примерно так

ALL ALL = (root) NOPASSWD: /usr/local/bin/bossy

И тогда вы бы использовали что-то вроде этого

A && sudo bossy && C

Для этого примера я предположил PATHвключает /usr/local/bin. Если нет, то просто используйте полный путь к скрипту, т.е.sudo /usr/local/bin/bossy

roaima
источник
Upvote для наиболее безопасного подхода.
eyoung100
0

Вы можете использовать как !requirettyопцию, sudoтак и NOPASSWDопцию. Но имейте в виду, что это снижает безопасность.

Стив Уиллс
источник
1
Поскольку проблема определяются как не хочу сценария быть интерактивными, # 2 с /etc/sudoersвходом для пользователя , чтобы выполнить команду Bс NOPASSWDправильным ответ.
Андрей
Это «ты мог сделать X или Y», это было «ты мог сделать X и Y». Только оба решат проблему. Возможно, мне следует перефразировать мой ответ.
Стив Уиллс,
0

Опираясь на мой ответ Предварительную авторизацию sudo? (Чтобы потом можно было запустить) , напишите два скрипта:

  • ABC_script:

    #!/bin/sh
    sudo -b ./B_script
    A  &&  > A_is_done
    while [ ! -f B_is_done ]
    do
            sleep 60
    done
    rm -f B_is_done
    C
  • B_script:

    #!/bin/sh
    while [ ! -f A_is_done ]
    do
            sleep 60
    done
    rm -f A_is_done
    B  &&  > B_is_done

Выполнить ./ABC_script:

  • Это будет работать sudo -b ./B_script. Это запрашивает пароль ( сразу после запуска ABC_script). Предполагая , что введен правильный пароль, он нерестится B_scriptв б ackground (потому что -bбыло указано) , как корень. Кажется, это эквивалентно sudo sh -c "./B_script &".
  • B_script начинает работать асинхронно, параллельно с ABC_scriptB_scriptпроверяет наличие файла с именем A_is_done and loop до его появления.
  • Параллельно ABC_scriptработаетA . Если / когда Aзаканчивается успешно, скрипт создает файл с именем A_is_done.
  • ABC_scriptзатем проверяет наличие файла с именем B_is_done and loop, пока он не появится.
  • Параллельно B_scriptобнаруживает существование A_is_doneи прерывает цикл. Удаляет A_is_doneфайл и запускается B. Помните, B_scriptон работает от имени пользователя root, поэтому он работает Bот имени пользователя root. Если / когда Bзаканчивается успешно, скрипт создает файл с именем B_is_doneи завершает работу.
  • Параллельно ABC_scriptобнаруживает существование B_is_doneи прерывает цикл. Удаляет B_is_doneфайл. Помните, что он B_scriptзапускается с правами root, поэтому B_is_doneон принадлежит root, и вы хотите использовать его, rm -fчтобы избежать получения запроса на подтверждение. ABC_scriptзатем бежит Cи выходит.

Примечания для дальнейшей доработки:

  • ABC_scriptдолжен, вероятно, работать B_scriptпо абсолютному пути, а не ./.
  • Вместо A_is_doneи B_is_done, ABC_scriptвероятно , должны генерироваться случайные, уникальные имена файлов.
  • Должно быть предусмотрено, что скрипт, ожидающий прокрутки, будет уведомлен, если ожидающая его программа завершилась, но завершилась неудачно. (Прямо сейчас, если происходит Aсбой, оба сценария просто переходят в бесконечный цикл ожидания.) Это может быть так же просто, как изменить

    A  &&  > A_is_done

    в

    A; echo $? > A_is_done

    а затем изменяете время ожидания для чтения X_is_doneфайлов и продолжаете, если оно содержит 0, и выходите в противном случае.

Скотт
источник
-3

Будь тупым. использовать много строк.

if A; then

    if sudo B ; then
        C
    fi
fi
Роберт Джейкобс
источник
как это решает мою проблему? Проблема не имеет ничего общего&&
Антуан Пелисс,
&& останавливает выполнение при сбое первой команды. Операторы if делают это более многословно. Моя цель - сделать вашу работу, даже если она не красивая.
Роберт Джейкобс
1
Это не более , чем более многословной версии варианта 2: A && sudo B && C. Так же, как Антуан объясняет в вопросе; он не запрашивает пароль до Aтех пор, пока не закончил, и он не хочет ждать этого, или сценарий ждет его.
Скотт