python subprocess: „su - -c” als Variable

OP #7882785

Hallo liebe Leser! Hab mir mal wieder ein wenig python Programmierung vorgenommen...!? Als Beispiel mal ein Verzeichnis als root erstellen, was so auch funktioniert:

1
Root = "su - -c"; Pfad = "/tmp/.abc/"; PfadTmp = "def"
2
subprocess.run(f"{Root} 'mkdir -p {Pfad}{PfadTmp}'", shell=True) # ok
3
subprocess.run(f"{Root} 'mkdir -p {Pfad}{PfadTmp}'", shell="/bin/bash") # ok
4
subprocess.run(["su", "-", "-c", 'mkdir -p ' + Pfad + PfadTmp]) # ok, ohne shell=irgendwas

shell=True soll man ja vermeiden, bliebe also nur der letzte Befehl. Das ich auch als User nach /tmp schreiben darf ist schon klar, darum gehts nicht da ich so einen Befehl in Variationen öfter brauche. Kann ich "su", "-", "-c" irgendwie funktionsfähig in eine Variable packen und falls ja, dann wie? Mit meinen Versuchen mit Root=... bin ich leider kläglich gescheitert! Der geneigte Leser darf mein Betriebssystem gern als debian erkennen...

Das Konzept an sich ist etwas fragwürdig, wenn ein Script Root braucht, startet man es halt als root, statt darin mit su herumzumachen, aber was solls...

Du könntest dir eine Funktion machen, in der du das Escaping machst, usw:

1
#!python3
2
def shell_escape(cmd):
3
    return ' '.join("'"+x.replace("'","'\\''")+"'" for x in cmd)
4
def as_root(cmd):
5
    return ['su', '-', '-c', shell_escape(cmd)]

Oder du könntest "sudo -- " stat "su - -c" nehmen, da musst du nur die Listen verketten, und musst das nicht mehr extra escapen.

shell=True sollte man ja vermeiden, damit man nicht je nach Shell falsch escapt, aber su -c führt das zeug auch in einer Shell aus, damit ist man wieder am Anfang.

1
#!python3
2
def as_root(cmd):
3
    return ['sudo', '--', *cmd]

Am besten wäre es aber immer, gar nicht erst root zu benötigen.

Peter N. schrieb:

Kann ich "su", "-", "-c" irgendwie funktionsfähig in eine Variable packen und falls ja, dann wie?

Klar, einfach dran denken, das die eckigen Klammern eine Liste bedeuten. (Und auch run eine liste erwartet)

1
root = ["su", "-", "-c"] 
2
# oder besser zu lessen:
3
root = "su - -c".split()
4

5
Pfad = "/tmp/.abc/"
6
PfadTmp = "def"
7

8
# und dann liste neinfach "addieren"
9
subprocess.run(root + ["mkdir -p " + Pfad+  PfadTmp])
OP

Aha, so geht das also! Vielen Dank Andreas, funktioniert perfekt:

1
Root = ["su", "-", "-c"]; Pfad = "/tmp/.abc/"; PfadTmp = "def"
2
subprocess.run(Root + ['mkdir -p ' + Pfad + PfadTmp])

Für die paar root Befehle die ich brauche möchte ich nicht das komplette Skript als root laufen lassen, da könnten verschiedene Änderungen schon verheerende Folgen haben... gelöst, größten Dank an alle Beteiligten!

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über ein Jahr alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.