Seite 1 von 1

Subprocess Problem

Verfasst: Montag 14. September 2009, 11:38
von Temoc
Hallo Freunde,

ich habe ein großes/kleines (Größen sind relativ) Python Problem.
Meine Ausgangssituation ist wiefolgt, ich möchte ein Ausführbare Datei unter Linux starten.
Diese befindet sich im Verzeichnis /home/rentd/services/vt2/127.0.0.1/3801 und trägt den Namen "ventrilo_svr".

Hier für nutze ich dann folgenden String/Befehl, um diese Auszuführen:
/home/rentd/services/vt2/127.0.0.1/3801/ventrilo_svr
Anbei jedoch, benötige ich einen Parameter: "-f/home/rentd/services/vt2/127.0.0.1/3801/ventrilo_svr"

Der komplette Zeile lautet dementsprechend:
/home/rentd/services/vt2/127.0.0.1/3801/ventrilo_svr -f/home/rentd/services/vt2/127.0.0.1/3801/ventrilo_svr
Wenn ich diese Zeile 1:1 in meiner /bin/bash ausführe, funktioniert es problemlos! Der Server startet korrekt und findet mit -f seine korrekten Pfade.
Auch wenn ich diese Zeile 1:1 in mein Pythonscript einbinde (siehe Quellcode), funktioniert es.

Nun ist es so, dass die IP/Port Variablen sind.. also ersetze ich diese durch meine eigenen Vars um das Python-Programm dynamisch zu machen.

Der IP und Port erhalte ich aus der Variable l_s[4] und ls_s[5] (Tuple-Typ). Wenn ich mir diese auf die Konsole printen lasse, ist auch alles korrekt. Auch die auszuführende Zeile, welche damit erstellt wird, wird korrekt dargestellt und erzeugt. Denn wenn ich diese Zeile selbst kopiere und einfüge in meiner Shell, startet der Serverdienst erfolgreich.

Quellcode (Server startet nicht korrekt):

Code: Alles auswählen

import subprocess

ExecuteLine = "/home/rentd/services/vt2/%s/%s/ventrilo_srv -f/home/rentd/services/vt2/%s/%s/ventrilo_srv" % (str(l_s[4]),str(l_s[5]),str(l_s[4]),str(l_s[5]))
# l_s[4] = 127.0.0.1
# l_s[5] = 3801

print "ExecuteLine: "+ExecuteLine
# print Ausgabe = "/home/rentd/services/vt2/127.0.0.1/3801/ventrilo_srv -f/home/rentd/services/vt2/127.0.0.1/3801/ventrilo_srv"

proc = subprocess.Popen([ExecuteLine], shell=True, executable='/bin/bash')
Der Dienst startet mit der Meldung:
Ventrilo Server - Version 2.1.2
(c)Copyright 1999-2003 Flagship Industries, Inc.

Server must have a valid name.
ERROR: Unable to read configuration data. Exiting
Nun starte ich den Dienst selbst, über die Ausgegeben Printzeile.
Ventrilo Server - Version 2.1.2
(c)Copyright 1999-2003 Flagship Industries, Inc.

20090914 12:31:55 Version = 2.1.2
20090914 12:31:55 Name = test123
Es funktioniert.

Aus Spaß habe ich diese Zeile 1:1 in meinen Pythonquellcode eingebaut.

Quellcode (Server startet, statischer Code):

Code: Alles auswählen

import subprocess

ExecuteLine = "/home/rentd/services/vt2/127.0.0.1/3801/ventrilo_srv -f/home/rentd/services/vt2/127.0.0.1/3801/ventrilo_srv"
# l_s[4] = 127.0.0.1
# l_s[5] = 3801

print "ExecuteLine: "+ExecuteLine
# print Ausgabe = "/home/rentd/services/vt2/127.0.0.1/3801/ventrilo_srv -f/home/rentd/services/vt2/127.0.0.1/3801/ventrilo_srv"

proc = subprocess.Popen([ExecuteLine], shell=True, executable='/bin/bash')
Der Code funktioniert. Das Problem besteht also dahin, dass wenn ich meine Variablen dort einsetze. Das Subprocess irgendwas falsch macht!
Ich bin mittlerweile am Ende. Vielleicht weiss einer von euch Rat. Umwandlung der Variablen mit str() bracht auch nichts.[/quote]

Verfasst: Montag 14. September 2009, 11:56
von Rebecca
Nicht so:

Code: Alles auswählen

subprocess.Popen(["ls -l"])
Sondern so:

Code: Alles auswählen

subprocess.Popen(["ls", "-l"])

Verfasst: Montag 14. September 2009, 12:07
von Temoc
Leider bringt dies auch nichts.

Hier der Quellcode:

Code: Alles auswählen

ExecuteLine_S = path+"ventrilo_srv "
ExecuteLine_P = "-f"+path+"ventrilo_srv"

# ExecuteLine_S = /home/rentd/services/vt2/195.13.63.151/3804/ventrilo_srv
# ExecuteLine_P = -f/home/rentd/services/vt2/195.13.63.151/3804/ventrilo_srv

proc = subprocess.Popen([ExecuteLine_S,ExecuteLine_P], shell=True, executable='/bin/bash')

Verfasst: Montag 14. September 2009, 12:10
von Hyperion
Für das Zusammensetzen von Pfaden gibt es os.join()!

Das hier sieht krude aus:

Code: Alles auswählen

ExecuteLine_P = "-f"+path+"ventrilo_srv"
Das "-f" ist doch ein Parameter! Wieso joinst Du den mit dem zugehörigen Wert? Du sollst diese Sachen ja gerade als Liste übergeben!

Verfasst: Montag 14. September 2009, 12:14
von Leonidas
Versuchs mal so:

Code: Alles auswählen

ExecuteLine_S = os.path.join(path, "ventrilo_srv")
ExecuteLine_P = "-f" + ExecuteLine_S

proc = subprocess.Popen([ExecuteLine_S, ExecuteLine_P])
(Das ganze ``shell=True``-Zeug ist total unnütz)

@Hyperion: einige Programme nehmen ihre Paramter im Format -fWERT und nicht -f WERT entgegen, von daher kann das durchaus richtig sein. Auch wenn diese Art Parameter zu übergeben ziemlich blödsinnig ist, aber da ist schon das aufzurufende Programm schuld.

Verfasst: Montag 14. September 2009, 12:19
von Hyperion
Leonidas hat geschrieben: @Hyperion: einige Programme nehmen ihre Paramter im Format -fWERT und nicht -f WERT entgegen, von daher kann das durchaus richtig sein. Auch wenn diese Art Parameter zu übergeben ziemlich blödsinnig ist, aber da ist schon das aufzurufende Programm schuld.
Hui, jetzt wo Dus sagst, stimmt. Ist mir irgend wann auch schon mal über den Weg gelaufen.

Verfasst: Montag 14. September 2009, 12:32
von Temoc
Leonidas hat geschrieben:Versuchs mal so:

Code: Alles auswählen

ExecuteLine_S = os.path.join(path, "ventrilo_srv")
ExecuteLine_P = "-f" + ExecuteLine_S

proc = subprocess.Popen([ExecuteLine_S, ExecuteLine_P])
(Das ganze ``shell=True``-Zeug ist total unnütz)

@Hyperion: einige Programme nehmen ihre Paramter im Format -fWERT und nicht -f WERT entgegen, von daher kann das durchaus richtig sein. Auch wenn diese Art Parameter zu übergeben ziemlich blödsinnig ist, aber da ist schon das aufzurufende Programm schuld.
Leider ebenfalls ohne Erfolg, das Programm gibt die typische "read error" Fehlermeldung.

Verfasst: Montag 14. September 2009, 12:57
von Temoc
Ich habe mal die Software hochgeladen, damit man das Problem selbst rekonstruieren könnte.

http://195.13.63.151/freiheit/vt2.tar.gz

Läuft unter x86-Architektur.

Habe das Programm in folgender Ordnerstruktur:
/home/rentd/services/vt2/127.0.0.1/3801/

Verfasst: Freitag 25. September 2009, 17:22
von Temoc
Darf man Threadpushing betreiben? :P

Re: Subprocess Problem

Verfasst: Dienstag 29. Juni 2010, 18:37
von Temoc
Habe festgestellt, dass es 1x mal funktioniert. Wenn ich jedoch einen zweiten Server starte, taucht das Problem wieder auf. Erst nach einem kompletten Neustart des Hardwareservers kann ich wieder das Script 1x erfolgreich ausführen, beim zweiten, dritten Start usw. funktioniert es wieder nicht.

Re: Subprocess Problem

Verfasst: Dienstag 29. Juni 2010, 20:02
von b.esser-wisser
"Geht nicht " ist die berühmte Nichtfehlermeldung :roll:
Gibt das Programm irgendwas aus (Wahrscheinlich auf stderr)?

"Server" klingt, als wären da evtl. noch ports/sockets belegt/übrig etc.

Re: Subprocess Problem

Verfasst: Dienstag 29. Juni 2010, 20:56
von Temoc
Als Fehlermeldung gibt es folgende Meldung:

Code: Alles auswählen

Ventrilo Server - Version 2.1.2
(c)Copyright 1999-2003 Flagship Industries, Inc.

Server must have a valid name.
ERROR: Unable to read configuration data. Exiting.

Re: Subprocess Problem

Verfasst: Dienstag 29. Juni 2010, 22:12
von BlackJack
@Temoc: Und wo und wie übergibst Du den Servernamen?

Re: Subprocess Problem

Verfasst: Mittwoch 30. Juni 2010, 23:02
von Temoc
Hallo,

ich konnte das Problem lösen. Es lag am vorherigen ConfigParser von Python, welchen ich nun durch ConfigObj ersetzt habe.

Habe euch mal beide Varianten bereitgestellt, ggf. findet jmd den Fehler durch eine tiefergehende Analyse...

Code: Alles auswählen

------------------------------------------------
--- DIE FOLGENDE VARIANTE FUNKTIONIERT NICHT ---
------------------------------------------------

vtc = ConfigParser.RawConfigParser()
cfgfile = open("ventrilo_srv.ini","w")
vtc.add_section('Server')
vtc.set('Server','Comment','- Ventrilo 2.1 Server')
vtc.set('Server','Port',"3801")
vtc.set('Server','AdminPassword','geheim')
vtc.set('Server','Password',"geheim")
vtc.set('Server','MaxClients',"8")
vtc.set('Server','Auth','1')
vtc.set('Server','Duplicates','0')
vtc.set('Server','SendBuffer','0')
vtc.set('Server','RecvBuffer','0')
vtc.set('Server','Diag','0')
vtc.set('Server','LogonTimeout','5')
vtc.set('Server','CloseStd','1')
vtc.set('Server','FilterWave','0')
vtc.set('Server','FilterTTS','0')
vtc.set('Server','TimeStamp','1')
vtc.set('Server','PingRate','10')
vtc.set('Server','ExtraBuffer','0')
vtc.set('Server','ChanWidth','0')
vtc.set('Server','ChanDepth','0')
vtc.set('Server','ChanClients','0')
vtc.set('Server','DisableQuit','1')
vtc.set('Server','VoiceCodec','0')
vtc.set('Server','VoiceFormat','3')
vtc.set('Server','SilentLobby','0')
vtc.set('Server','Name',"Servername")
vtc.add_section('Status')
vtc.set('Status','Intf',"10.10.10.10")
vtc.add_section('Intf')
vtc.set('Intf','Intf',"10.10.10.10")
vtc.write(cfgfile)

------------------------------------------
--- DIE FOLGENDE VARIANTE FUNKTIONIERT ---
------------------------------------------

config = ConfigObj()
config.filename = "ventrilo_srv.ini"

section1 = {
	'Intf': '10.10.10.10',
}
config['Intf'] = section1
config['Status'] = section1
section2 = {
	'Comment': '- Ventrilo 2.1 Server',
	'Port': '3801',
	'AdminPassword': 'geheim',
	'Password': 'geheim',
	'MaxClients': '8',
	'Auth': '1',
	'Duplicates': '0',
	'SendBuffer': '0',
	'RecvBuffer': '0',
	'Diag': '0',
	'LogonTimeout': '5',
	'CloseStd': '1',
	'FilterWave': '0',
	'FilterTTS': '0',
	'TimeStamp': '1',
	'PingRate': '10',
	'ExtraBuffer': '0',
	'ChanWidth': '0',
	'ChanDepth': '0',
	'ChanClients': '0',
	'DisableQuit': '1',
	'VoiceCodec': '0',
	'VoiceFormat': '3',
	'SilentLobby': '0',
	'Name': "Servername",
}
config['Server'] = section2
config.write()

Re: Subprocess Problem

Verfasst: Donnerstag 1. Juli 2010, 07:37
von lunar
Die erste Variante kann auch allenfalls durch einen glücklichen Zufalls funktionieren. Die Konfigurationsdatei, welche Du zum Schreiben geöffnet hast, wird nie geschlossen. Daher verbleiben die geschriebenen Daten im Puffer der E/A-Schicht, der gestartete Dienst sieht immer nur eine leere Datei.

Merke: Dateien immer korrekt schließen. Am besten verwendest Du zur Arbeit mit Dateien oder allgemein jeder Art von Ressource die "with"-Anweisung. Mehr dazu steht in der Dokumentation.

Re: Subprocess Problem

Verfasst: Donnerstag 1. Juli 2010, 13:05
von Temoc
Wie kann ich denn die Datei korrekt schließen, magst es mir verraten? :-)

Re: Subprocess Problem

Verfasst: Donnerstag 1. Juli 2010, 13:34
von Dav1d
In dem man sie schließt, mit .close() oder mit "with"

Code: Alles auswählen

with open('my_file.txt', 'w') as f:
    f.write('asd')
# hier gehts weiter

Re: Subprocess Problem

Verfasst: Donnerstag 1. Juli 2010, 13:42
von lunar
@Temoc: Nun, Du kannst auch einfach die Dokumentation lesen ...

Re: Subprocess Problem

Verfasst: Donnerstag 1. Juli 2010, 14:14
von cofi
lunar hat geschrieben:@Temoc: Nun, Du kannst auch einfach die Dokumentation lesen ...
http://docs.python.org/tutorial/inputou ... ting-files

Re: Subprocess Problem

Verfasst: Donnerstag 1. Juli 2010, 14:22
von Temoc
Wär ja nicht so, als würde ich nicht den halben Tag davor sitzen... aber dennoch danke für eure Hilfe.