Seite 1 von 1

Variablenaufruf in subprocess

Verfasst: Freitag 19. März 2010, 00:34
von c0mp4ct
Hallo Community,

ich bin dabei ein paar bash scripte nach python zu "exportieren". Dabei bräuchte ich einen Tipp wie sich dies bewerkstelligen lässt. Hier mein code:

Code: Alles auswählen

#!/usr/bin/env python
import subprocess

intro = raw_input("Hier beginnt das Script")

subprocess.call("echo -e $intro", shell=True)
Dies ist ein einfaches Beispiel, es geht darum die $intro variable "global" zu setzen, sodas diese auch in subprocess.call verfügbar ist. Für echo kann auch jedes beliebige andere Programm stehen, welches die Eingabe eines String benötigt und sollte fortlaufend ausgeführt werden. Hoffe ihr könnt mir dabei helfen.

Gruß Tim

Verfasst: Freitag 19. März 2010, 01:02
von Anaconda

Code: Alles auswählen

subprocess.call(["echo", "-e", intro], shell=True)
Das $ wird in Python nicht verwendet für Variablen,wie in Bash.

Verfasst: Freitag 19. März 2010, 01:11
von lunar
@Anaconda: Das funktioniert nicht, der Grund steht in der subprocess-Dokumentation. Richtig wäre es ohne shell=True und komplett getrennten Argumenten:

Code: Alles auswählen

subprocess.call(['echo', '-e', intro])
Alternativ (wenn man tatsächlich echtes Shell-Verhalten möchte) kann man den "env"-Parameter nutzen:

Code: Alles auswählen

env = dict(os.environ)
env['intro'] = 'intro'
subprocess.call('echo -e $intro', shell=True, env=env)
Auf "shell=True" sollte man aber nach Möglichkeit verzichten.

Verfasst: Freitag 19. März 2010, 01:17
von Anaconda
Du hast Recht. Ich war etwas schnell und hatte einfach seine Codezeile an der Stell mit der Variable editiert.

Verfasst: Freitag 19. März 2010, 01:38
von c0mp4ct
Mit dem Weg von Lunar klappt es wunderbar. Natürlich muss man für env noch os importieren (vollständigkeitshalber). Habe noch ein paar Fragen zu deinem Post:

1.) warum sollte man auf "shell=True" verzichten?
2.) wie würde denn das Verhalten ohne Shell ($) aussehen?

Würde das ganze dann auch gerne komplett in Python schreiben.

Vielen Dank!

Verfasst: Freitag 19. März 2010, 02:10
von BlackJack
@c0mp4ct: Auf ``shell=True`` sollte man verzichten weil man damit in der Regel völlig unnötig eine Shell startet, die dann das startet was man angegeben hat, statt direkt das zu starten, was man eigentlich ausführen möchte.

Je nach Shell kann das Verhalten unterschiedlich sein. Zum Beispiel gibt's unter Unix verschiedene Shells, die sich nicht in allen Details gleich verhalten. Ganz zu schweigen von anderen Betriebssystemen, denn die `command.com` oder `cmd.exe` unter Windows verhalten sich ziemlich anders als Unix-Shells. Da müsste man Umgebungsvariablen, die man vorher mit `os.env` bekannt gemacht hat, zum Beispiel als '%foo%' statt als '$foo' angeben.

Bei einer Shell bekommt man ausserdem den Rückgabewert der *Shell*. Das *kann* der Rückgabewert des gestarteten Programms sein, *muss* es aber nicht.

Die zweite Frage verstehe ich nicht!? Lunar hat doch gezeigt wie man es ohne Shell macht. Und das sollte sich verhalten wie mit der Shell, nur eben ohne die Probleme, die man sich damit einhandeln kann.

Shell macht nur Sinn, wenn man Shell-interne Befehle ausführen will. Aber selbst da würde ich explizit die gewünschte Shell mit entsprechenden Argumenten aufrufen.

Verfasst: Freitag 19. März 2010, 10:23
von c0mp4ct
Ok, das habe ich verstanden. Frage 2 hat sich erledigt, weil ich nicht gesehen habe das lunar den code von Anaconda editiert hat (dachte war nur ein Zitat).
Bei mir haben jetzt beide Wege funktioniert, wobei der ohne env natürlich besser ist. Läuft auch problemlos mit mehreren Variablen.
Vielen Dank an euch.

Jetzt muss ich nur noch herausfinden wie man mit Python eine neue shell öffnet :wink:

Verfasst: Freitag 19. März 2010, 10:47
von snafu
Nenne doch vielleicht mal das Ziel deines Vorhabens...

Verfasst: Freitag 19. März 2010, 12:02
von c0mp4ct
Ziel soll es sein, ein Pythonscript per Konsole zu starten. Dieses startet einen Server mit Parameter die ich vorher per raw_input übergebe (funktioniert auch). Die Konsole dient dazu die Servermeldungen 1zu1 mitzuverfolgen. Jedoch bin ich jetzt dabei ein script für 2 Server zu schreiben, weswegen ich auch 2 Konsolen brauche um die Meldungen zu verfolgen bzw. um gleich wieder eine normale Konsole vor mir zu haben.

Edit hier die Lösung:

Code: Alles auswählen

subprocess.call(['konsole'])