python subprocess: „su - -c” als Variable

OP #7882785
Lesenswert?
• ▲
▼

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...

#7882845
Lesenswert?
• ▲
▼

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.

#7882858
Lesenswert?
• ▲
▼

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 #7882906
Lesenswert?
• ▲
▼

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

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

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.