Problem mit os.popen() und telnet

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
Roman
User
Beiträge: 65
Registriert: Dienstag 14. März 2006, 09:10
Wohnort: Berlin

Hallo,
Ich habe ein Problem mit os.popen, wenn ich telnet aufrufen möchte.
Ich versuche, eine Verbindung zu einem Server herzustellen, um mit diesem zu kommunizieren, komme aber nicht weiter, weil os.popen nicht funktioniert bzw. nichts zurückgibt.

Code: Alles auswählen

>>> import os
>>> antwort=os.popen('telnet mail.orcon.net 25')
>>> antwort.read()
''
Eigentlich erwarte ich, dass in dem file Daten über die Verbindung zum Server stehen. :? Einen Fehler mit dem DOS Befehl kann ich nicht gemacht haben, denn der funktioniert wunderbar, wenn ich ihn direkt in die command-line eingebe...
Kann mir da jemand helfen?
Danke schon mal im Voraus,
Roman :D
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Roman hat geschrieben:wenn ich telnet aufrufen möchte.
Hi Roman!

Wenn nichts weiterhilft, dann geht pexpect, aber nur unter Linux:
http://pexpect.sourceforge.net/

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
modelnine
User
Beiträge: 670
Registriert: Sonntag 15. Januar 2006, 18:42
Wohnort: Celle
Kontaktdaten:

Um Gerolds Antwort zu erweitern: es hilft auch die Verwendung des pty-Wrapper-Moduls. telnet kommuniziert nicht mit stdin/stdout, sondern mit den darunterliegenden (Pseudo-)Terminals, da es selbst ein Terminal emuliert, und zur Ausgabe des ganzen nicht die Möglichkeiten ausreichen, die stdin/stdout als "einfache" Filedeskriptoren zur Verfügung stellen.

pexpect ist nichts anderes als ein pty-Wrapper-Wrapper, der das Umgehen mit den Pseudo-Terminals ein bisschen angenehmer macht.
--- Heiko.
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

modelnine hat geschrieben:telnet kommuniziert nicht mit stdin/stdout.
Mmh, bei mir (Linux-PC) sieht es aber so aus, als taete telnet das:

Code: Alles auswählen

>>> [stdout, stdin, stderr] = popen2.popen3("telnet mail.orcon.net 25")
>>> print stdout.read()
Trying 219.88.242.10...

>>>
>>> print stderr.read()
telnet: connect to address 219.88.242.10: Connection refused

>>> 
Und:

Code: Alles auswählen

rbreu@abby:~> echo "open mail.orcon.net 25" | telnet > stdout.txt 2>stderr.txt
rbreu@abby:~> cat stdout.txt 
telnet> Trying 219.88.242.10...
telnet> 
rbreu@abby:~> cat stderr.txt 
telnet: connect to address 219.88.242.10: Connection refused
Das mag natuerlich unter DOS anders sein, aber da hilft einem pty dann auch nicht.
modelnine
User
Beiträge: 670
Registriert: Sonntag 15. Januar 2006, 18:42
Wohnort: Celle
Kontaktdaten:

Mmh, bei mir (Linux-PC) sieht es aber so aus, als taete telnet das
Huh? Das tut's bei mir nur, solange die Verbindung geöffnet wird (und da tatsächlich, das wusste ich nicht). Sobald eine Verbindung offen ist wird bei mir nix mehr über stdin/stdout geschickt (wenn ich das "richtige" Telnet-Protokoll mit Terminal-Emulation nutze, und nicht telnet auf port 25, oder sowas, wo die automatisch ausgeschaltet ist, und wo's weiterhin auf stdin/stdout geht).
--- Heiko.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Roman hat geschrieben:Einen Fehler mit dem DOS Befehl kann ich nicht gemacht haben
Hi Roman!

Ich lese soeben, dass du DOS(Windows) einsetzt. Da geht pexpect natürlich nicht. Ausgenommen du installierst Cygwin.

Aber, wie wäre es damit? http://python.org/doc/2.4.3/lib/telnet-example.html

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Oder einbfach die smtplib, wenn du es nicht so Lowlevel willst.

Und, etwas näher an den Sockets: asynchat.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Roman
User
Beiträge: 65
Registriert: Dienstag 14. März 2006, 09:10
Wohnort: Berlin

Danke für eure zahlreichen Antworten, ihr habt mir sehr geholfen :D
Da ich Windows benutze, (Hm, ich hätte das vielleicht vorher erwähnen sollen :oops: ) ist Gerolds Beispiel genau das richtige für mich... Genau dieses Programm wollte ich schreiben.
Allerdings habe ich das mit den Terminals und dem stdin/stdout nicht wirklich geblickt, da ich alles in allem noch ein rechter Python-Neuling bin :?
Mfg,
Roman
PS: Das soll euch nicht von weiteren Diskussionen abhalten... :D
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Roman hat geschrieben:Allerdings habe ich das mit den Terminals und dem stdin/stdout nicht wirklich geblickt, da ich alles in allem noch ein rechter Python-Neuling bin
Das hat mit Python speziell nix zu tun. Was ich jetzt schreibe, gilt fuer Linux, aber sollte bei Windows nicht viel anders sein:

Die meisten Prozesse oeffnen drei Filedescriptoren: stdin, stdout, stderr. Von sdtin liest ein Prozess die Eingabe, nach stdout schreibt er seine Ausgabe, und nach stderr Fehlermeldungen. Normalerweise sorgt die Shell (oder die Eingabeaufforderung oder was immer) dafuer, dass das, was der User eintippt, nach stdin des enstprechenden Prozesses geleitet wird, und dass der Inhalt von stdout und stderr in der Shell ausgegeben wird. Man kann die Ein/Ausgabe in/aus den Filedescriptoren aber auch umlenken.

Code: Alles auswählen

stdin.txt > meinprogramm > stdout.txt 2> stderr.txt
zum Beispiel liest die Eingabe nicht mehr vom Shell-Prompt, sondern aus der Datei stdin.txt, und schreibt seine Ausgabe in stderr.txt und sdtout.txt.

popen macht nix anderes, als dir diese Filedescriptoren zur Verfuegung zu stellen, sodass du davon lesen oder da reinschreiben kannst.

Es gibt aber auch Programme (telnet, ssh,...), die nicht die Filedescriptoren sdtin/stdout/stderr benutzen. Da scheitert popen dann. Stattdessen wollen solche Prozesse "interaktive Terminals"...
Roman
User
Beiträge: 65
Registriert: Dienstag 14. März 2006, 09:10
Wohnort: Berlin

Danke... Ich bin schon oft über diese Begriffe gestolpert, habe aber nie richtig verstanden worum es dabei ging :oops:
Jetzt habe ich es aber gerafft! :D
Noch eine Frage: Warum will z.B. telnet ein Terminal und nicht die stdin/out/err Filedescriptoren sondern diese Terminals? Und was muss ich mir unter denen vorstellen? Muss ich dann die Daten in die Terminals reinschreiben bze. aus ihnen auslesen?
Danke schon mal im Voraus,
Roman
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Roman hat geschrieben:Noch eine Frage: Warum will z.B. telnet ein Terminal und nicht die stdin/out/err Filedescriptoren sondern diese Terminals?
stdstreams kann man, nachdem man in sie geschreiben hat, nicht mehr ändern. Dagegen kannst man in Terminals "zeichen", also den Cursor in diesem Terminal an eine belibige stelle stellen und dort etwas ausgeben. Genau das nutzt telnet. So kannst du auch ncurses-Programme über telnet nutzen, ansonsten könntest du nichteinmal die [Backspace]-Taste verwenden.

Siehe Terminalemulation.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Urspruenglich war ein Terminal ein reales Geraet mit Bildschirm und Tastatur, welches die Daten, die der User eintippt, an einen Prozess weiterreicht. Bestimmte Eingaben (Escape-Sequenzen) werden aber nicht weitergereicht, so sorgt z.B. Ctrl-C dafuer, dass der Prozess abgebrochen wird, Ctrl-S stoppt ihn etc.

Unter Unix/Linux gibt es sogenannte Pseudoterminals, die so ein Geraet emulieren. Das ist nichts anderes als eine bestimmte Art, zwei Prozesse miteinander kommunizieren zu lassen. Letzendlich kann man da auch wieder mittels eines Filedescriptors lesen und schreiben, das ist aber ziemlich lowlevel.

Wikipedia weiss mehr:
http://de.wikipedia.org/wiki/Terminal_(Computer)
http://de.wikipedia.org/wiki/Pseudoterminal

Warum manche Prozesse partout Terminals wollen, habe ich mich auch gefragt. Da es sich meistens um "sicherheits-sensible" Programme handelt (wo man Passwoerter eingeben muss etc.), schaetze ich, dass das eine Sicherheitsfrage ist. Es wird verhindert, dass man z.B. einfach ein Passwort aus einer Datei uebergeben kann usw, sondern im Regelfall muss ein User dasitzen und alles eintippen.

Aber letztendlich kann man das ja (unter Linux/Unix zumidest mit Peudoterminals) umgehen und dem Programm vorgaukeln, es haette mit einem echten User zu tun. :roll: Aber wie gesagt, sowas wie Pseudoterminals gibt es unter Windows nicht...

(Obwohl, die Eingabeaufforderung muss ja dem Telnet auch ein Terminal vorgaukeln, oder? Naja, reinste Spekulation, ich kenn mich mit Windows nich wirklich gut aus.)

EDIT: Hui, habe ich lange fuer diesen Post gebraucht :shock: Als ich anfing, war Leonidas Post noch nicht da...
Roman
User
Beiträge: 65
Registriert: Dienstag 14. März 2006, 09:10
Wohnort: Berlin

Also von dem was ich so von wikipedia verstanden habe, ist so eine Terminalemulation nichts anderes als ein weitgefasster parser, oder?
Die Emulation übersetzt quasi die Ausgabe eines Prozesses und leitet sie an einen anderen Prozess weiter... Ist das so richtig?
EIn parser macht ja im Grunde auch nichts anderes... Er "übersetzt" eine Syntax in eine andere.
Ich habe allerdings noch keinen Blick in die anderen Links geworfen, kann also sein, dass da anderes drinsteht.
Danke für eure Mühe,
Roman :D
Antworten