Der folgende Code gibt einen Fehler aus, wenn er von einem Nicht-Root-Benutzer für eine Datei im Besitz von root ausgeführt wird, auch wenn der Nicht-Root-Benutzer über sudo-Berechtigungen verfügt:
%Vor% Gibt es eine Möglichkeit, open(filename, "w+")
mit sudo-Rechten auszuführen, oder eine alternative Funktion, die das tut?
Sie haben ein paar Optionen:
os.geteuid() != 0
), und rufen Sie sich dann mit sudo
infront an (wodurch der Benutzer zur Eingabe seines Passworts aufgefordert wird) und beenden Sie: %Vor%
Der Aufruf sieht so aus:
%Vor% Die Möglichkeit, sudo
zu verwenden, gibt Ihnen keine Privilegien, wenn Sie sie nicht benutzen. So wie andere Leute vorgeschlagen haben, solltest du dein Programm einfach mit sudo
starten. Aber wenn Sie diese Idee nicht mögen (ich sehe keinen Grund dafür), können Sie einen anderen Trick machen.
Ihr Skript kann prüfen, ob es mit Root-Rechten oder nur mit Benutzerrechten ausgeführt wird. Als Skript kann sich tatsächlich mit höheren Rechten ausführen. Hier haben Sie ein Beispiel (bitte beachten Sie, dass das Speichern des Passworts im Quellcode keine gute Idee ist).
%Vor%Ausgabe:
%Vor%Ihr Skript ist auf die Berechtigungen beschränkt, mit denen es ausgeführt wird, da Sie Benutzer nicht ändern können, ohne bereits Root-Rechte zu besitzen.
Wie Rob sagte, ist die einzige Möglichkeit, dies zu tun, ohne Ihre Dateiberechtigungen zu ändern, die Ausführung mit sudo
.
L3viathan's Antwort hat einen SynaxError -Editor: funktioniert gut mit Python 3.5+. Hier ist eine Version für Python 3.4.3 (standardmäßig auf Ubuntu 16.04 verteilt) und unten:
Ich ging jedoch mit einem anderen Ansatz vor, weil es den Code in meinem Anwendungsfall einfacher machte:
%Vor%L3viathans Antwort hängt von PEP 448 , das in Python 3.5 enthalten war und zusätzliche Kontexte eingeführt hat, in denen die Erweiterung von Sternargumenten erlaubt ist. Für Python 3.4 und darunter kann Listenverkettung verwendet werden, um das Gleiche zu tun:
%Vor% Aber Hinweis: subprocess.call()
startet einen untergeordneten Prozess, dh nachdem root das Skript ausgeführt hat, wird der ursprüngliche Benutzer auch weiterhin sein Skript ausführen. Das bedeutet, dass Sie die erhöhte Logik auf eine Seite eines if/else
-Blocks setzen müssen. Wenn das ursprüngliche Skript beendet ist, versucht es nicht, irgendeine Logik auszuführen, die eine Erhöhung erfordert (L3viathan's Beispiel tut dies).
Das ist nicht unbedingt eine schlechte Sache - es bedeutet, dass normale / erhöhte Logik im selben Skript geschrieben und schön getrennt werden kann - aber meine Aufgabe benötigte root für die gesamte Logik. Ich wollte keine Einrückungsebene verschwenden, wenn der andere Block leer sein würde, und ich hatte nicht bemerkt, wie die Verwendung eines Child-Prozesses die Dinge beeinflussen würde, also habe ich Folgendes versucht:
%Vor%... und es ging natürlich kaputt, denn nachdem root fertig war, nahm der normale Benutzer die Ausführung seines Skripts wieder auf und versuchte, die Anweisungen auszuführen, die root erforderten.
Dann fand ich diesen Gist , der os.execvp()
empfiehlt - was den laufenden Prozess ersetzt, anstatt ein Kind zu starten:
Dies verhält sich wie erwartet, speichert eine Einrückungsstufe und 3 Zeilen Code.
Vorbehalt: Ich wusste vor zehn Minuten noch nichts über os.execvp()
und weiß noch nichts über mögliche Fallstricke oder Feinheiten um seine Verwendung herum. YMMV.
Tags und Links python ioerror file-writing