Выполните первую часть кода от имени root, вторую часть от имени другого пользователя

#python #bash #root #popen

#питон #баш #корень #попен

Вопрос:

У меня возникли проблемы с получением некоторого кода для работы. У меня есть некоторая интерактивная программа, которая состоит из двух частей для выполнения:

1 — Он должен убедиться, что некоторые каталоги имеют надлежащие разрешения. В принципе все просто chown . Эта часть должна быть выполнена как root в соответствии с системными требованиями.

2 — Он должен выполнить некоторый код от имени другого пользователя, к которому пользователь root обычно может su подключиться без какого-либо пароля.

Я пытался использовать подпроцесс.Popen() без особой удачи, есть ли у кого-нибудь какие-либо идеи о том, как это сделать? Заранее спасибо!

Комментарии:

1. пользовательская команда sudo -u

2. Если интерактивная программа является внешне выполняемой программой, т.Е. Не Является частью вашего кода Python? Существует ли только одна программа? Нужно ли ему получать и отказываться от корневых разрешений в разное время, или ему просто нужны права root только один раз в начале?

3. Интерактивная программа написана на python и в идеале должна быть частью того же скрипта python, но я мог бы жить со скриптом-оболочкой. Этот интерактивный скрипт не обязательно должен быть root, мне просто нужны эти разрешения в начале, чтобы выполнить chown

4. У вас есть пароль? Затем вы могли бы обернуть его в expect и запустить свое приложение на python с помощью скрипта bash.

5. Это именно то, что я в итоге сделал. Я создал лаунчер в bash и использовал su для запуска python от имени другого пользователя

Ответ №1:

В итоге я создал скрипт bash, который должен выполняться от имени root, поэтому он сначала выполняет chown, а затем выполняет бит python. Что-то вроде этого:

 #!/bin/bash

chown -R user:user /path/to/change
su -c 'python3 -c "first python step; second python step"' user
 

Я использую опции -c как su, так и python3, чтобы указать, какие команды выполнять и от имени какого пользователя их выполнять.

Ответ №2:

Я думаю, это должно помочь (как инструкции ‘bash’).

(все, что после # в коде, — это мои комментарии)

Разделите код на две части — для ‘root’ (суперпользователь) и $USER (другие пользователи).
Проверьте, не является ли это ‘root’; ЗАТЕМ сделайте что-нибудь…

 if [ $(whoami) != 'root' ]; then
  # do some $USER instructions...
 

$(...) — оболочка для выполнения команд
whoami — вывести эффективный идентификатор пользователя

ЕЩЕ (если это ‘root’) выполните некоторые инструкции суперпользователя…

 else
  # do some 'root' instructions
fi # end of 'IF' condition
 

В разделе $USER ( $(whoami) != 'root' ) при необходимости запустите этот скрипт с правами root. И вы можете передать аргумент (например, ‘DO_CHOWN’) как вызов для определенного действия:

 sudo -s "$0" DO_CHOWN
 

sudo — запустить команду от имени суперпользователя (по умолчанию)
-s — сохранит текущий путь к скрипту
$0 — текущий скрипт с путем
DO_CHOWN — любой аргумент (имя не имеет значения), который мы передаем, чтобы получить

После использования sudo вам будет предложено ввести пароль для доступа.
Если вы не хотите постоянно вводить пароль.
Вы можете использовать что-то вроде этого:

 echo 'yourpassword' | sudo -Ss "$0" DO_CHOWN
 

echo — выводит данные
| — (pipe) перенаправляет вывод, в данном случае, из echo sudo
-S — запишет вывод из «echo» в приглашение

В разделе ‘root’ (else) нам нужно получить аргумент (‘DO_CHOWN’), который мы передали.
Что-то вроде этого:

 if [[ $@ =~ 'DO_CHOWN' ]]; then
  # do chown instructions...
  exit
fi
 

$@ — все аргументы переданы скрипту
=~ — ищет совпадение со значением, указанным справа
exit — завершить процесс

Окончательный код:

 # IF not 'root'
if [ $(whoami) != 'root' ]; then
  echo 'User:' $(whoami) # show current username
  echo 'Path:' $(pwd) # show current directory of the script
  sudo -s "$0" DO_CHOWN # send 'DO_CHOWN' argument as a call for a specific action
  # THEN enter your password, OR:
  # echo 'yourpassword' | sudo -Ss "$0" DO_CHOWN # to not enter the password manually
  echo "Continue as $(whoami)..."
# IF 'root'
else
  echo 'User:' $(whoami)
  echo 'Path:' $(pwd)
  # IF get the 'DO_CHOWN' argument
  if [[ $@ =~ 'DO_CHOWN' ]]; then
    echo 'do chown instructions...'
    exit
  fi
fi
 

Консольный вывод:

 User: user_name
Path: /home/user_name
[sudo] password for user_name:
User: root
Path: /home/user_name
do chown instructions...
Continue as user_name...
 

Нравится. Подписка. Комментарий 😉👍

Комментарии:

1. Пожалуйста, предоставьте небольшое объяснение; ответы только для кода, даже если они правильные, мало что делают, чтобы помочь OP выяснить, что они сделали неправильно.

2. Код довольно хорошо прокомментирован, и я могу его понять, хотя я согласен, что некоторые письменные объяснения были бы полезны для тех, кто не знаком с bash

3. @SuperStar, описал, как мог 😅👍

4. @JavierRieraChirivella Ок. Спасибо 😉👍