@mutetella:
Deiner Annahme, die Ausgabe von sys.stdout.write('\033[18t') am STDIN lesen zu können, liegt ein Misverständnis über die Funktionsweise von Terminals zugrunde.
Kurze Erklärung hierzu:
Ausgehend vom einfachsten Fall, dem klassischen Textterminal, haben wir 2 Komponenten auf Terminalseite - eine Eingabe (Tastatur) und eine Ausgabe (Display). Das Programm, welches STDIN, STDOUT und STDERR erhält, "sitzt" dem Terminal gegenüber (hier dein Pythonscript). In der Terminalgrundeinstellung wird STDIN von der Eingabe des Terminals gefüttert (Du tippst etwas und kannst es im Programm am STDIN lesen) und
gleichzeitig vom Terminaltreiber an die Ausgabe weitergeleitet (ECHO, Du siehst was Du tippst quasi sofort auf dem Display). Alles was dein Programm nach STDOUT schreibt landet in der Ausgabe und nicht nochmal im STDIN. Und das ist nämlich hier der Fall - Du schreibst nach STDOUT.
Jetzt fragst Du Dich wahrscheinlich, warum da etwas ganz anderes ankommt, als Du geschrieben hast. Der Grund dafür ist - Terminals verhalten sich wie Pipes mit der Möglichkeit zur Interpretation der Daten (von einfacher Datenmanipulation bis zu komplexen Zustandsänderungen des Terminals).
Das Ganze wird im Falle von Pseudoterminals und Terminalemulatoren unter X noch etwas komplizierter, da hier die "Geräteseite" (master) vom Emulator, also wiederum einem Programm, repräsentiert wird. Die Kaskade für xterm sieht dann stark vereinfacht ungefähr so aus:
Code: Alles auswählen
Ein-/ausgabe (Monitor + Keyboardtreiber im Kernel) <---> Systemkonsole <---> X (routet Key- und Displayevents) <---> Terminalemulator (xterm) <---> Python
Trotzdem ist es möglich, an die Ausgabe von sys.stdout.write('\033[18t') ranzukommen, Bsp:
Code: Alles auswählen
import os, sys
from select import poll, POLLIN
from posix_term import cbreak_terminal
# echo und kanonischer Modus off
with cbreak_terminal():
# hole terminal des programms
slave = os.ttyname(0)
f = os.open(slave, os.O_RDONLY)
# nutzt poll um zu prüfen, ob Daten am Terminal eingegangen sind
poll_obj = poll()
poll_obj.register(f, POLLIN)
sys.stdout.write('\033[18t')
sys.stdout.flush()
result = 'nix'
# falls Daten am Terminal lies sie in result ein
for fd, event in poll_obj.poll(10):
if fd == f and event & POLLIN:
result = os.read(f, 1024)
print repr(result)
os.close(f)
Da das Terminal, mit welchem Dein Programm verbunden ist, selbst als dateiähnliches Gerät vorliegt, kannst Du hier mitlesen. Allerdings musst Du das Terminal vorher manipulieren und wenigstens den kanonischen Modus abschalten (evtl. noch das ECHO, beides macht hier das
cbreak_terminal()), um an die Ausgabe ranzukommen.
Die Methode ist alles andere als zuverlässig oder terminalübergreifend, bei mir interpretiert nur xterm die Escapesequenz entsprechend Deiner Vorgabe. Auch ist es nicht ungefährlich, so auf das Terminal zuzugreifen, da andere Datenstöme (z.B. eine zeitgleiche Eingabe) korrumpiert werden können.