Запустите os.system, как будто Python не был выполнен с помощью sudo - PullRequest
0 голосов
/ 03 марта 2019

Когда я запускаю следующую команду, все работает как положено.Нет ошибки, и я получаю системное уведомление «Hello»:

$ python3
>>> import os
>>> os.system("notify-send Hello")
0

Однако, когда я делаю это:

$ sudo python3
>>> import os
>>> os.system("notify-send Hello")

Сценарий зависает, и ничего не происходит.

Затем я попытался сделать это:

$ sudo python3
>>> import os
>>> os.seteuid(1000)
>>> os.system("notify-send Hello")

(1000 - моя обычная учетная запись пользователя без полномочий root)
Но, тем не менее, скрипт застревает и ничего не происходит.

Я также попробовал это:

$ sudo python3
>>> import os
>>> os.system("su my-user-name -c 'notify-send Hello'")

и это:

$ sudo python3
>>> import os
>>> os.seteuid(1000)
>>> os.system("su my-user-name -c 'notify-send Hello'")

У них у всех одна и та же проблема ...

Я не ищу альтернативуспособ создания уведомлений.Меня не интересуют subprocess или такие вещи, как notify2, которые вызывают совершенно новую категорию проблем в моей системе.О, и, пожалуйста, не говорите мне не использовать sudo.У меня есть свои причины.

1 Ответ

0 голосов
/ 04 марта 2019

Детализация реализации, которую я обнаружил методом проб и ошибок: notify-send требует, чтобы переменная окружения XDG_RUNTIME_DIR работала - по крайней мере, в следующих версиях:

$ dpkg -l | grep libnotify
ii  libnotify-bin                              0.7.7-3                                      amd64        sends desktop notifications to a notification daemon (Utilities)
ii  libnotify4:amd64                           0.7.7-3                                      amd64        sends desktop notifications to a notification daemon

Сначала я определил еенужна была какая-то переменная окружения с использованием env -i notify-send hello, которая не производила уведомлений.

Затем я разделил пополам среду с измененной версией этот скрипт

Как вы получаетеэта переменная окружения зависит от вас, но вы должны запускать notify-send от имени соответствующего пользователя и с этим набором переменных.

Вот пример скрипта на python, я отказываюсь использовать os.system из-за его безопасностипроблемы:

import os
import pwd
import subprocess
import sys


def main():
    if len(sys.argv) != 2:
        raise SystemExit(f'usage `{sys.argv[0]} USER`')
    if os.getuid() != 0:
        raise SystemExit('expected to run as root')

    # find the `gnome-session` executable, we'll use that to grab
    # XDG_RUNTIME_DIR
    cmd = ('pgrep', '-u', sys.argv[1], 'gnome-session')
    pid = int(subprocess.check_output(cmd))

    # read that process's environment
    with open(f'/proc/{pid}/environ') as f:
        for line in f.read().split('\0'):
            if line.startswith('XDG_RUNTIME_DIR='):
                _, _, xdg_runtime_dir = line.partition('=')
                break
        else:
            raise SystemExit('Could not find XDG_RUNTIME_DIR')

    # run the notify send as the right user
    uid = pwd.getpwnam(sys.argv[1]).pw_uid
    os.seteuid(uid)
    os.environ['XDG_RUNTIME_DIR'] = xdg_runtime_dir
    os.execvp('notify-send', ('notify-send', 'ohai'))


if __name__ == '__main__':
    exit(main())

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ : этот скрипт делает некоторые очень хакерские вещи, которые я не обязательно предлагал бы в производственном коде.В частности:

  • Обращение к pgrep для поиска процесса
  • чтение переменных среды другого процесса
  • sudo

Пример использования:

$ python3 t.py
usage `t.py USER`
$ python3 t.py asottile
expected to run as root
$ sudo python3 t.py asottile
# (I get a notification for `ohai`)
...