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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren