Seite 1 von 1

subprocess

Verfasst: Montag 24. Mai 2010, 10:44
von INFACT
Hi,

Ich versuche gerade einen cmd ersatz für windows zu programmieren.
Das Fenster und so gibt es alles schon, jetzt muss ich aber die Befehle "popen".
Das ist mein Code, den ich bis jetzt geschrieben habe:

Code: Alles auswählen

    def executeInput(self, input):
        sp = subprocess.Popen(input,
                              stdout=subprocess.PIPE,
                              stderr=subprocess.PIPE)
        print ":", sp.stdout.read()
Da habe ich jetzt aber 2 probleme:
1. subprocess führt keine Befehle wie cls oder echo aus. Mit IF habe ich das noch nicht probiert.
2. Was ist denn wenn jetzt ein programm einen input in stdin will? Dann wird mein programm gedost :lol:

Habt ihr irgenteine Idee wie man das verhindern kann?

Edit:

Code: Alles auswählen

 statt [code] verwendet

Re: subprocess

Verfasst: Montag 24. Mai 2010, 11:07
von BlackJack
@INFACT: Wenn Du einen `cmd.exe`-Ersatz schreiben willst, dann musst Du natürlich auch die eingebauten Befehle und die Programmflusskontrolle mit bedingter Ausführung, Schleifen und so weiter auch selber implementieren. Ebenso die Umleitung von und in Dateien.

Ausserdem musst Du dafür Sorge tragen, dass bei Programmen die auf `stderr` *und* `stdout` Ausgaben tätigen, Dein `cmd.exe`-Ersatz nicht blockiert.

Re: subprocess

Verfasst: Montag 24. Mai 2010, 11:08
von Hyperion
INFACT hat geschrieben: Das Fenster und so gibt es alles schon,
Was genau meinst Du damit?
1. subprocess führt keine Befehle wie cls oder echo aus. Mit IF habe ich das noch nicht probiert.
Woran erkennst Du denn, dass der Befehl nicht ausgeführt wird?

Re: subprocess

Verfasst: Montag 24. Mai 2010, 11:14
von INFACT
Na toll,

ich wollte eigentlich nur eine coole shell wie bei ubuntu xtce4-terminal .
Wo man verschiedene Farben(für dieses root@rootpc$, stdout, stderr) und Hintergrund (Bilder, Transparenz) optionen und so hat.

Ich hab gedacht das währe leichter, weil ich das mit den Farben und Transparenz mit PyQt schon mal gemacht habe. Ich habe aber nicht gedacht, dass das so schwer währe die eingaben vernünftig zu programmieren.

Kennt jemand sowas vielleicht oder muss ich das doch programmieren? :mrgreen:

Re: subprocess

Verfasst: Montag 24. Mai 2010, 11:34
von INFACT
Hyperion hat geschrieben:
INFACT hat geschrieben: Das Fenster und so gibt es alles schon,
Was genau meinst Du damit?
Das ich das schon in PyQt4 programmiert habe, also das Gui gibt es schon, nur die Funktionen fehlen
Hyperion hat geschrieben:
1. subprocess führt keine Befehle wie cls oder echo aus. Mit IF habe ich das noch nicht probiert.
Woran erkennst Du denn, dass der Befehl nicht ausgeführt wird?

Code: Alles auswählen

>>> subprocess.call("echo Hi")
Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    subprocess.call("echo Hi")
  File "E:\Python26\Lib\subprocess.py", line 444, in call
    return Popen(*popenargs, **kwargs).wait()
  File "E:\Python26\Lib\subprocess.py", line 595, in __init__
    errread, errwrite)
  File "E:\Python26\Lib\subprocess.py", line 821, in _execute_child
    startupinfo)
WindowsError: [Error 2] The system cannot find the file specified

Re: subprocess

Verfasst: Montag 24. Mai 2010, 11:52
von Hyperion
Naja, wie BlackJack schon schrieb: Du musst halt gucken, welche Kommandos Du an das OS weiterreichen kannst und welche Du selber ausführen musst. Dazu kommt dann noch die entsprechende Ein- / Ausgabeumleitung.

Prinzipiell durchaus eine nette Idee, die durchaus viel Spaß machen kann. Man muss ja auch nicht gleich alles können. Speziell Verschachtelungen oder Schleifen kann man ja auch erst einmal weglassen; diese spielen ja eher bei Scripten eine Rolle - und die kann ich ja auch in der echten DOS-Shell ablaufen lassen.

Re: subprocess

Verfasst: Montag 24. Mai 2010, 12:37
von INFACT
Hab schonmal gefunden wie ich mit subprocess alle befehle ausführen kann:

Code: Alles auswählen

subprocess.Popen('cmd /c "example.bat"')
führt dann diese batch aus:

Code: Alles auswählen

@echo off
echo Hi
pause > nul
Ich kann so auch direkt pause > nul aufrufen.

Für Linuxe: pause > nul heißt einfach das der "Eine beliebige Taste drücken schreibt. und man dann ANY KEY drücken muss.
> nul ist wie > /dev/null

Jetzt muss ich nur noch rausfinden wie ich mit subprocess herausfinden kann ob das programm auf eine Eingabe wartet und die dann ausführt.

Re: subprocess

Verfasst: Montag 24. Mai 2010, 13:00
von BlackJack
@INFACT: Wenn Du die Eingaben mit `cmd.exe` ausführst um `cmd.exe` zu ersetzen, dann scheint mir das ziemlich Sinnlos!?

Kann es sein dass Du eigentlich gar keine Shell sondern ein Terminal implementieren möchtest? Dann musst Du überhaupt keine Befehle selber implementieren, sondern einfach nur eine grafische Umgebung für die `cmd.exe` schaffen. Also diese einmal starten und die Ein- und Ausgaben mit Deinem Code verbinden. Eventuell musst Du ein Pseudoterminal emulieren damit diese Kanäle nicht gepuffert werden. Ist jedenfalls unter Linux der Fall.

Re: subprocess

Verfasst: Montag 24. Mai 2010, 13:12
von INFACT
BlackJack hat geschrieben:@INFACT: Wenn Du die Eingaben mit `cmd.exe` ausführst um `cmd.exe` zu ersetzen, dann scheint mir das ziemlich Sinnlos!?

Kann es sein dass Du eigentlich gar keine Shell sondern ein Terminal implementieren möchtest? Dann musst Du überhaupt keine Befehle selber implementieren, sondern einfach nur eine grafische Umgebung für die `cmd.exe` schaffen. Also diese einmal starten und die Ein- und Ausgaben mit Deinem Code verbinden. Eventuell musst Du ein Pseudoterminal emulieren damit diese Kanäle nicht gepuffert werden. Ist jedenfalls unter Linux der Fall.
Oh, ä,

Ja das meinte ich :roll: :roll: :roll:

Mist.
Ich versuche gerade stdin richtig hinzubekommen.

Code: Alles auswählen

>>> p = Popen("cmd w", stdout=subprocess.PIPE,
	  stderr=subprocess.PIPE)
>>> p.stdout.read() # das was am anfang im cmd steht
'Microsoft Windows [Version 6.1.7600]\r\nCopyright (c) 2009 Microsoft Corporation.  All rights reserved.\r\n\r\nE:\\Python26>'
>>> p.communicate("echo test") # sollte dann echo test ins cmd eingeben
('', '')
>>> p.stdout.read() # hier sollte dann test stehen 1.)
''
>>> p.stdout.read()
''
Bei 1.) Sollte test stehen, weil man ja echo test ins cmd eingegeben hat.
Wieso klappt das nicht!?

EDIT: bei stderr ist auch nichts zu finden

Re: subprocess

Verfasst: Montag 24. Mai 2010, 15:32
von Dav1d
Du solltest die Dokumentation zu subprocess lesen, unbedingt!
Speziell den Abschnitt stdout.read(), stderr.read(), stdin.write() und popen.communicate()

Anbei noch ein Link, der dir vllt. auf die Sprünge helfen kann: http://blog.dav1d.de/code/subprocess-un ... us-stdout/

Re: subprocess

Verfasst: Montag 24. Mai 2010, 18:08
von INFACT
Ja da ist ein problem.

Wenn ich stdin mit pipe mache, dann bekomme ich kein richtiges realtimeoutput.

Code: Alles auswählen

>>> from subprocess import Popen, PIPE
>>> p = Popen("cmd w",
	  stdout=PIPE,
	  stderr=PIPE,
	  stdin=PIPE)
>>> while True:
    line = p.stdout.readline()
    if not line:
        break
    print 'STDOUT>>> ' + repr(line)#.rstrip()

    
STDOUT>>> 'Microsoft Windows [Version 6.1.7600]\r\n'
STDOUT>>> 'Copyright (c) 2009 Microsoft Corporation.  All rights reserved.\r\n'
STDOUT>>> '\r\n'
Aber das hört nicht auf, also break wird nie ausgeführt.


Und wenn ich stdin nicht als parameter angebe, cann ich auch stdin.write nicht ausführen.

Re: subprocess

Verfasst: Montag 24. Mai 2010, 18:49
von Dav1d
Du beendest auch den cmd.exe Prozess nie (das geht z.B. mit exit)

Re: subprocess

Verfasst: Montag 24. Mai 2010, 19:48
von INFACT
Wenn ich vorher stdin.write("exit\r\n"), dann wird das beendet.

Dann muss ich aber doch das lesen und schreiben in 2 threads ausführen, oder?
Wenn mir read erst etwas ausgibt, wenn da was neues steht.

Hier mal ein nicht funktionierendes beispiel:

Code: Alles auswählen

>>> from subprocess import Popen, PIPE
>>> p = Popen("cmd w",
          stdout=PIPE,
          stderr=PIPE,
          stdin=PIPE)
>>> def readThread():
	while True:
	    line = p.stdout.readline()
	    if not line:
		break
	    print 'STDOUT>>> ' + repr(line)#.rstrip()

	    
>>> import thread
>>> thread.start_new_thread(readThread, tuple())
5956STDOUT>>> 'Microsoft Windows [Version 6.1.7600]\r\n'

STDOUT>>> 'Copyright (c) 2009 Microsoft Corporation.  All rights reserved.\r\n'
>>> 
STDOUT>>> '\r\n'
p.stdout.write("echo test\r\n")
dir()
pass
exit()
# hier passiert irgentwie nichts

Re: subprocess

Verfasst: Montag 24. Mai 2010, 22:19
von ichisich
Hi,

ohne jetzt dein Problem ganz genau durchgegangen zu sein...
Ich hab neulich Bekanntschaft mit QProcess gemacht und mich um etliches leichter getan als mit subprocess.
Da du ja schon mit PyQt schaffst wäre das auf alle Fälle nen Blick wert.
(Evt ist es aber einfach nur geschmacksache und mir liegt die Doku von Qt besser und sämtliche Funktionen in QProcess und subprocess sind redundant)

Gruß

Re: subprocess

Verfasst: Dienstag 25. Mai 2010, 12:50
von Dav1d
Wieso probierst du in der IDLE, das gibt nur ärger?
Mache die auserdem mal mit Queue.Queue vertraut