source scripts subproces - best practise ?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
HBerger
User
Beiträge: 9
Registriert: Montag 23. August 2021, 13:29

Hallo miteinander,

Ich komme nicht aus der Python Welt, also sorry für die Frage ... :geek:

Der Kontext worum es geht ist CI, also pure Terminal / Shell Anwendungen
leider wird unser Build-system immer komplexer -> man muss befehle mit zig Argumenten aufrufen, die sich keiner merken kann, aber eigentlich klar sind, wenn man das System kennt.
leider wird die Logik auch immer komplexer und ich mag PowerShell und komplexe Windows Batches nicht (eh doof weil nicht Plattform übergreifend)
deshalb -> Python.

das nur als Einleitung, sorry :-)

Mein Problem:
bevor ich meine Befehle abfeuern kann, muss ich oft generierte Batchfiles "sourcen" also "call <ziemlich komplexer pfad hier>\XXX.bat"
typische Beispiele sind vcvars.bat / conanbuild.bat
die meisten Batches setzen nur Environment variables

Wie löst man das eigentlich elegant in Kombination mit Python und subprocess?

Der erste Impuls wäre eine eigene Batch zu generieren / schreiben und dann auszuführen.
find ich aber nicht ganz so elegant.

Gibt's da was anderes ?
kann man in Python eine Batch ausführen und danach die Environment variablen irgendwie abfragen / speichern?

Gibt's sowas wie eine Terminal Abstraktion, den man Befehle quasi senden kann, die dann in der selben Session ausgeführt werden?

Leider rufen grad vcvars.bat und conanbuild.bat andere Batches auf , so das die Batches parsen und direkt ein Environment erzeugen wahnsinnig komplex werden würde.
conan generiert ein env file, was man parsen kann, aber eben nur conan. ich bräuchte was generisches
imonbln
User
Beiträge: 207
Registriert: Freitag 3. Dezember 2021, 17:07

Wie immer bei solchen Fragen gibt es mehrere Wege zum Erfolg. Bei den meisten Funktionen in subprocess kann man ein Mapping als Parameter env übergeben.

Im einfachsten Fall ist ein solches Mapping ein Python-Dictionary. Dieses Mapping entspricht dann dem Environment, das der Subprocess sieht.

Eine Lösung könnte also sein, in deinem Python-Skript ein Dictionary aufzubauen, welches deine Environment-Variablen kennt, und das dann als subprocess.run(..., env=my_dict) dem Subprocess zu übergeben.
Ich bin ein Freund von der Trennung von Daten und Code, daher würde ich das Dictionary wahrscheinlich über eine TOML-, Konfigurations- oder JSON-Datei befüllen.

Alternativ kannst du auch das Python-Modul dotenv installieren, welches automatisch den Inhalt einer .env-Datei in das Environment appliziert und für solche Sachen gedacht ist.
Sirius3
User
Beiträge: 18409
Registriert: Sonntag 21. Oktober 2012, 17:20

@HBerger: wenn Du mehrere Skripte nacheinander ausführen möchtest, kannst Du sie per && koppeln.

Code: Alles auswählen

subprocess.run("call vcvars.bat && call build.bat", shell=True)
Schön ist das natürlich nicht.
Du kannst natürlich dir die Environment-Variablen geben lassen und beim richtigen Aufruf per env= mitgeben:

Code: Alles auswählen

subprocess.run("call vcvars.bat && set", shell=True)
Benutzeravatar
__blackjack__
User
Beiträge: 14401
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Wobei man die Ausgabe von ``set`` dann auch wieder parsen muss, oder?

Ist PowerShell nicht grundsätzlich auch portabel? Ich habe hier unter Linux mal eine installiert.

Edit: Habe das gerade mal hier ausprobiert die Umgebungsvariablen als JSON von der PowerShell zu bekommen:

Code: Alles auswählen

PS /home/bj> Get-ChildItem Env: | Select 'key', 'value' | ConvertTo-Json
[
  {
    "Key": "_",
    "Value": "/snap/bin/powershell"
  },
  {
    "Key": "CLR_ICU_VERSION_OVERRIDE",
    "Value": "70.1"
  },
  {
    "Key": "CLUTTER_IM_MODULE",
    "Value": "xim"
  },
  {
    "Key": "COLORFGBG",
    "Value": "15;0"
  },
  {
    "Key": "COLORTERM",
    "Value": "truecolor"
  },
...
“It is well known that a vital ingredient of success is not knowing that what you're attempting can't be done.”
— Terry Pratchett, Equal Rites
Antworten