Судо в неінтерактивному сценарії


9

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

Функція Bповинна бути запущена як супер-користувач, в той час Aі Cне роблять.

У мене є кілька рішень, але жодне з них не задовольняє:

  1. Судо весь сценарій: sudo 'A && B && C'

    Це здається поганою ідеєю запускати Aі Cяк суперкористувача, якщо це не потрібно

  2. зробити сценарій інтерактивним: A && sudo B && C

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

  3. Дурне рішення: sudo : && A && sudo -n B && C

    По-перше, здається, що дурно запускати sudoспочатку неоперацію , а також я повинен перетнути пальцем, що A не збирається брати більше, ніж $sudo_timeout.

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

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

    Це запросить мій пароль на початку, а потім використовувати ці облікові дані лише за потреби.

Яка ваша думка щодо всього цього? Я був би дуже здивований, що для цієї проблеми немає рішення, тому що я думаю, що це досить поширена проблема (що стосується make all && sudo make install)


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

Відповіді:


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


Оновлення найбільш безпечного підходу.
eyoung100

0

Можливо, ви хочете використовувати !requirettyопцію sudoяк і NOPASSWDопцію. Але майте на увазі, це знижує безпеку.


1
Оскільки проблема визначаються як не хочу сценарію бути інтерактивними, # 2 з /etc/sudoersвходом для користувача , щоб виконати команду Bз NOPASSWDправильним відповідь.
Андрій

Це "ви могли зробити X або Y", це було "ви могли зробити X і Y". Тільки обидва вирішать проблему. Можливо, я повинен переказати свою відповідь.
Стів Віллз

0

Спираючись на мою відповідь на попереднє дозвіл на судо? (Щоб це можна було запустити пізніше) , напишіть два сценарії:

  • 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з'являється на b ackground (тому що -bбуло вказано) як root. Це здається рівнозначним sudo sh -c "./B_script &".
  • B_scriptпочинає працювати асинхронно, паралельно з ABC_scriptB_scriptтести на існування файлу, який називається, A_is_done і циклічно, поки він не з'явиться.
  • Паралельно ABC_scriptбігає A. Якщо / коли Aзавершується успішно, сценарій створює файл, який називається A_is_done.
  • ABC_scriptпотім тестує наявність файлу, який називається, B_is_done і циклічно, поки він не з'явиться.
  • Паралельно 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не закінчиться, і він не хоче цього чекати, або сценарій чекатиме його.
Скотт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.