This is a follow-up question of Use tkinter based PySimpleGUI as root user via pkexec.

I have a Python GUI application. It should be able to run as user and as root. For the latter I know I have to set $DISPLAY and $XAUTHORITY to get a GUI application work under root. I use pkexec to start that application as root.

I assume the problem is how I use os.getexecvp() to call pkexec with all its arguments. But I don't know how to fix this. In the linked previous question and answer it works when calling pkexec directly via bash.

For that example the full path of the script should be/home/user/x.py.

#!/usr/bin/env python3
# FILENAME need to be x.py !!!
import os
import sys
import getpass
import PySimpleGUI as sg


def main_as_root():
    # See: https://stackoverflow.com/q/74840452
    cmd = ['pkexec',
           'env',
           f'DISPLAY={os.environ["DISPLAY"]}',
           f'XAUTHORITY={os.environ["XAUTHORITY"]}',
           f'{sys.executable} /home/user/x.py']

    # output here is
    # ['pkexec', 'env', 'DISPLAY=:0.0', 'XAUTHORITY=/home/user/.Xauthority', '/usr/bin/python3 ./x.py']
    print(cmd)

    # replace the process
    os.execvp(cmd[0], cmd)


def main():
    main_window = sg.Window(title=f'Run as "{getpass.getuser()}".',
                            layout=[[]], margins=(100, 50))
    main_window.read()


if __name__ == '__main__':
    if len(sys.argv) == 2 and sys.argv[1] == 'root':
        main_as_root()  # no return because of os.execvp()

    # else
    main()

Calling that script as /home/user/x.py root means that the script will call itself again via pkexec. I got this output (self translated to English from German).

['pkexec', 'env', 'DISPLAY=:0.0', 'XAUTHORITY=/home/user/.Xauthority', '/usr/bin/python3 /home/user/x.py']
/usr/bin/env: „/usr/bin/python3 /home/user/x.py“: File or folder not found
/usr/bin/env: Use -[v]S, to takeover options via #!

For me it looks like that the python3 part of the command is interpreted by env and not pkexec. Some is not as expected while interpreting the cmd via os.pkexec().

But when I do this on the shell it works well.

pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY python3 /home/user/x.py
1

There are 1 answers

0
buhtz On

Based on @TheLizzard comment. The approach itself is fine and has no problem.

Just the last element in the command array cmd. It should be splitted.

cmd = ['pkexec',
       'env',
       f'DISPLAY={os.environ["DISPLAY"]}',
       f'XAUTHORITY={os.environ["XAUTHORITY"]}',
       f'{sys.executable}',
       '/home/user/x.py']