I am writing a python3 app, running with a GUI (not in the terminal) as the user. While this app is running as the user, I need to also execute a command that requires root privileges. I've seen numerous examples of how to do this in the terminal, like this one, which does in fact work great in the terminal:
import subprocess
subprocess.call('sudo echo "Hello world!"', shell=True)
...but my python app is not running in the terminal, and this method doesn't seem to automatically provoke a visible system prompt when my GUI code calls it.
Other apps, notably the Snap Store, somehow launch what appears to be a system popup when they need to do something with root privileges. For example, when I use the Snap Store to install Notepad++ on Ubuntu, I get this popup, which I suspect is a system popup rather than something the Snap Store folks custom-designed.
I'm not super familiar with Linux systems, but I assume this is not a custom popup instead of a system popup because who wants to give their root password to the makers of one of their apps? Instead, users would be giving it to the system (which already knows it), and the 3rd-party app itself doesn't have access to the actual password, but can now run a command as root.
How can I launch an identical popup from my Python app in order to run a command that requires root privileges? Or, alternatively, how else can I run a root command from my python GUI running as the user?
Thanks in advance for any clear assistance you can provide!
Have you tried pkexec?
Not sure about your GUI but running a simple python script (python3.8, pycharm, ubuntu 18.04) results in the popup you desire (can't do the screen print of the pop-up).
import os
os.system("pkexec ls -l")
Related
Wish You all beautiful sunny day! :D,
I have a question for You guys. I have following python "script":
import os
os.system('ubuntu.exe')
Which opens Ubuntu running on my WSL. And now, when the Ubuntu terminal appears:
I would like to execute following commands: sudo /etc/init.d/dbus start and sudo /etc/init.d/xrdp start using my python script (just do them automatically). However, when I run one of the commands above, terminal requests my password:
So the script should be also able to enter the password.
Is there any way, how to do it?
Kind regards,
D.
While the question/answers linked in the comments is a good read (sudoers in particular), there's a better method for WSL. Instead of using ubuntu.exe, use the newer wsl.exe replacement. The wsl command offers more control over the startup, including being able to change the user:
import os
os.system('wsl ~ -u root -e sh -c "nohup service xrdp start"')
os.system('wsl -u root service dbus start')
The nohup is needed because of what seems to be a timing issue. When starting up via the WSL command, the shell (owning process) will terminate before xrdp gets a chance to fork. nohup just makes sure that the full xrdp init script gets a chance to run before that happens. This really isn't a WSL issue, per se. It can also be replicated if you were do something similar with exec sh -c "sudo service xrdp start".
A couple of other notes. First, this does not require a password, since WSL doesn't have the concept of "login." The /init process (WSL's PID1 and initialization) is responsible for setting the owning user for each session. This is not considered a security risk since even the root WSL user runs with no greater than the permissions of the Windows user.
Also note that, in my experience, it's not necessary to start dbus for xrdp access, even though I've seen instructions that say it is. Ultimately it will depend on what you want to run within the xrdp session, of course.
I would like to have an executable (Windows, MacOS, Linux) of my program that will have its own terminal window where users will be able to type in. I don't want to have the user install modules or anything except this executable. You could say that the UI of my program would be a terminal window. Is it possible and with what?
I basically want the GUI of my app to be a terminal window.
To create a command-line interface for your program you'll likely want to use something like argparse, which is in the standard Python library. There are many other feature-rich command-line interface modules (e.g., click) you could try to use instead. You can design command-line interactions for your users including input and output, menus, etc.
Once you've built your application, a good choice to make it portable is the PyInstaller module. If you set the --onefile option when invoking it, it will generate a single .exe file which can be easily shared with users. If you also set the --console option when invoking PyInstaller, then your Python .exe application will interface with stdin/stdout. On Windows, this would be a cmd window.
If a user invokes your .exe via the GUI (e.g., a double-click on its icon), a Windows CMD window will be opened. If you want that window to stay open, however, you will need to create your application with some kind of "infinite"/"captive" design that never finishes executing until the user explicitly quits.
If the user instead runs the .exe from a Windows CMD terminal that is already open, then that window will always stay open.
I suspect you're looking for curses, or UniCurses if you're stuck with Microsoft Windows.
Many terminal emulators will allow you to start them up with a command line option that specifies a command to run in that emulator instead of your default shell.
I've scoured the interwebs and couldn't find anything with python, android, and "shortcut" or "home-screen" to appear on the same page. I have pydroid3 installed, working great. I'd like to have a shortcut (ideally on the home-screen) that I can tap once and have it run without opening the IDE for editing.
Making a shortcut to the file, or opening a source file in the file manager will at best just open it in the pydroid3 IDE, at worst state "this file type is not supported."
At the beginning of the script, I have tried putting "#!/user/data/../pydroid_dir/python", but alas the OS doesn't realize I mean to run it directly in the python interpreter. Any solutions or alternative lines of thinking are appreciated!
EDIT
I'm running an unrooted android 9 PIE. I wanted to provide some more details but not quite a solution for any readers. Check out related question: How to create a homescreen shortcut to launch a shell script?. Closest I got was trying SManager which allows you to create a homescreen shortcut to a shell script. Your shell script could be hardcoded to call python on your script:
/path/to/python /path/to/python/script
Unfortunately, if you're phone is not rooted, you may not have permission to execute whatever version of python you're calling outside of the context of the app it was installed for. Also, you have to ensure that your shell and python scripts reside in an appropriate place for execution. If your phone is rooted, SManager seems to have options to let you run the script as root.
pydroid3 allows me to run scripts residing on my internal storage as well as lets them read and write files at that location. That's why I was hoping that there was a pydroid way to create a shortcut (or an alternative python app that does this) since it has appropriate privileges.
QPython OL lets you create home screen shortcuts to python scripts on Android. First tap on the 'Q' icon at the top of the main screen (it took me a while to realise this was a button), then long-press on the script you want. This should give you a prompt to create a shortcut, as in the screenshots below.
QPython 3L also claims to have similar functionality when you long-press a script in its 'Programs' section. At time of writing (Jun 20) this seems to be broken.
I've not tried Pydroid myself, but haven't come across anything claiming it could create script shortcuts either.
You can use Termux:Widget as a command line to execute a python script. In Termux you can not create GUI with tkinter. You have to launch X-Server with VNC Mobile client. The widget is like a small shell prompt.
When I install the Google App Engine SDK and run the launcher, it asks me to configure the python location:
And when I open Preferences, it asks for a path to a python executable:
Which path should I insert and what is the difference:
C:\Python27\python.exe
C:\Python27\pythonw.exe
Looks like Google App Engine couldn't find your python installation. It looks for Python by checking the PATH environment variable, so it's best to use it.
The short answer is use C:\Python27\pythonw.exe. I've just installed the latest "GoogleAppEngine-1.9.33.msi", and after I ran "Google App Engine launcher" (C:\Program Files (x86)\Google\google_appengine\launcher\GoogleAppEngineLauncher.exe), in "Edit -> Preferences" I saw "C:\Python35\pythonw.exe". (It is because I have Python 3.5 folder before Python 2.7 folder in my Path environment variable setting.) But the point is App Engine launcher (or installer) chose the pythonw.exe over python.exe all by itself.
But as a better solution, I would suggest you to set your Path environment variable, this will prevent other similar issues in the future.
To set Python on the Path, if it's not set:
Right click "Computer" (or "My Computer") and choose "System Properties";
Switch to "Advanced" tab;
Press "Environment variables" button;
Double click "Path" variable in the lower list of system variables;
In the opened window in "Values" add C:\Python27\;C:\Python27\Scripts; to the beginning of the line. Make sure you don't accidently delete anything there!
Press "OK" in this window and "OK" in "Environment variables" window and you're good to go.
Alternatively in item 5, you might want to use user's PATH from the upper list. I would set Python for all users as I described.
Now launch Google App Engine via "Google App Engine Launcher" and see if in "Edit -> Preferences" you have either "Default if not set: C:\Python27\pythonw.exe" or "Default if not set: C:\Python27\python.exe" written below the field for "Python path". If there's still nothing similar, then it's not the launcher that checks for PATH, but it's the Installer. Then now it's time to uninstall "Google App Engine" and install it again. After this everything should work as expected. (Btw, Installer checks for Python and other dependecies, so it should report if there're any errors.)
The main difference between python.exe and pythonw.exe is:
python.exe opens console widow when a module is executed with it,
or, if run directly from command line, executes a module in a current
console window preventing any further commands until the module
exits. So basically intended for console applications or debugging.
pythonw.exe on the other hand is intended for GUI apps or no-GUI
apps, so if a module is executed with pythonw.exe, then there's no
console window is open, if run via current console a module is
executed in a separate process and the console is available for further
commands right away. The drawback is no output is provided in this
case, i.e. no errors printed as there's no console window associated
with running Python module.
Fore details see: official docs, chapter from a book(small but informative), Python mailing list.
Now regarding Google App Engine, on installation page they state:
You will need Python 2.7 to use the App Engine SDK, because the
Development Server is a Python application. Download Python 2.7.X
(don't use a higher version) from the Python web site.
So since a server is a no-GUI application, that's probably why App Engine chooses pythonw.exe.
According to this QA, pythonw seems to be preferable:
https://code.google.com/p/googleappengine/issues/detail?id=11246
Here's the similiar question and answer:
pythonw.exe or python.exe?
python.exe is a console (terminal) application for launching CLI-type scripts.
pythonw.exe is a GUI app for launching GUI/no-UI-at-all scripts.
From looking at the the docs: https://docs.python.org/2/using/windows.html#executing-scripts
Pythonw basically suppresses the console window. I wouldn't think you'd need one using the app-engine, so, pythonw.exe would be my best guess.
Pythonw.exe is the executable that does not open the console. Python.exe will open the console. You probably want to use pythonw.exe in this instance because I don't know why you would want a terminal open for the app engine.
https://docs.python.org/2/using/windows.html
The App Engine SDK also didn't find your installation of python. This is probably because you don't have the global env. variable declared.
The error message says python=None. Check if you can execute from cmd python -V to confirm your python build is accessible throughout the system. GAE generally can find your python installation automatically, and confirms your python path before installation.
Try this tutorial if its any help.
I'm trying to hide the Terminal when I launch a GUI Tkinter based app, but when I double click the app.py file on OSX, the Terminal window appears. I've tried changing the extension to .pyw and tried launching it with /usr/bin/pythonw, but no matter what, the Terminal window still appears.
I've even tried adding the try/except below, but when I run it I get the error: 'invalid command name "console"' in the Terminal window that appears.
from Tkinter import *
class MainWindow(Tk):
def __init__(self):
Tk.__init__(self)
try:
self.tk.call('console', 'hide')
except TclError, err:
print err
win = MainWindow()
win.mainloop()
I haven't been able to find any way to hide the Terminal window from appearing. Anybody got any ideas?
By double-clicking a .py file on OS X, you are likely launching a Python gui instance via the Python Launcher.app supplied with OS X Pythons. You can verify that by selecting the .py file in the Finder and doing a Get Info on it. Python Launcher is a very simple-minded app that starts Python via a Terminal.app command. To directly launch your own Python GUI app, the preferred approach is to create a simple app using py2app. There's a brief tutorial here.
EDIT:
There are other ways, of course, but most likely any of them would be adding more levels of indirection. To make a normal launchable, "double-clickable" application, you need some sort of app structure. That's what py2app lets you create directly.
A very simple-minded alternative is to take advantage of the AppleScript Editor's ability to create a launcher app. In the AppleScript editor:
/Applications/Utilities/AppleScript
Editor.app in OS X 10.6
/Applications/AppleScript/Script
Editor.app in 10.5
make a new script similar to this:
do shell script "/path/to/python /path/to/script.py &> /dev/null &"
and then Save As.. with File Format -> Application. Then you'll have a double-clickable app that will launch another app. You can create something similar with Apple's Automater.app. But, under the covers, they are doing something similar to what py2app does for you, just with more layers on top.
Adding to the answer by Ned Deily, im my case when I tried to launch the Python application using an AppleScript application, it did not work initially. I discovered that it has something to to with some kind of encoding error (I am using UTF-8 and in the past I had felt need to configure it to UTF-8).
So, after further investigation, I discovered that I can accomplish this by creating an AppleScript application with the following code (adjusting the paths of python3 and of the Python application as needed):
do shell script "export LC_ALL=en_US.UTF-8; export LANG=en_US.UTF-8; /usr/local/bin/python3 '/Users/USER/FOLDER/SCRIPT.py' &> /dev/null &"
It launches the Python application without any Terminal windows. The AppleScript application can then be personalised with a custom icon as usual, and can be placed in the Dock. When clicked, it will launch the Python intepreter, that still shows up in Dock, but with no visible windows.
I think this may be useful to other users.
'console hide' doesn't hide the Terminal in OS X. It hides Tk's built-in console, which is really a relic from the MacOS Classic days (and which is still commonly used on Windows).