Seite 1 von 1
Problem mit os.popen() und telnet
Verfasst: Donnerstag 20. April 2006, 06:59
von Roman
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

Re: Problem mit os.popen() und telnet
Verfasst: Donnerstag 20. April 2006, 07:21
von gerold
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

Verfasst: Donnerstag 20. April 2006, 07:24
von modelnine
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.
Verfasst: Donnerstag 20. April 2006, 07:57
von Rebecca
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.
Verfasst: Donnerstag 20. April 2006, 08:05
von modelnine
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).
Re: Problem mit os.popen() und telnet
Verfasst: Donnerstag 20. April 2006, 08:14
von gerold
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

Verfasst: Donnerstag 20. April 2006, 10:06
von Leonidas
Oder einbfach die
smtplib, wenn du es nicht so Lowlevel willst.
Und, etwas näher an den Sockets:
asynchat.
Verfasst: Freitag 21. April 2006, 09:05
von Roman
Danke für eure zahlreichen Antworten, ihr habt mir sehr geholfen
Da ich Windows benutze, (Hm, ich hätte das vielleicht vorher erwähnen sollen

) 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...

Verfasst: Freitag 21. April 2006, 09:38
von Rebecca
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.
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"...
Verfasst: Freitag 21. April 2006, 11:14
von Roman
Danke... Ich bin schon oft über diese Begriffe gestolpert, habe aber nie richtig verstanden worum es dabei ging
Jetzt habe ich es aber gerafft!
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
Verfasst: Freitag 21. April 2006, 12:08
von Leonidas
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.
Verfasst: Freitag 21. April 2006, 12:21
von Rebecca
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.

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

Als ich anfing, war Leonidas Post noch nicht da...
Verfasst: Freitag 21. April 2006, 12:58
von Roman
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
