less mit python

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
Pygoscelis papua
User
Beiträge: 206
Registriert: Freitag 13. März 2015, 18:36

gibt es eine möglichkeit ein "less" ähnliches Programm mit python zu schreiben?
Mein problem ist dabei: ich kann nicht gleichzeitig von einer Pipe den input holen und von der Tastatureingabe, weil die Pipe ja die Informationen über stdin sendet.

Hat jemand eine Idee wie man das zugleich verwenden kann?
import this
hidden python features

JAVA = Just Another Vulnerability Announcement :D
BlackJack

@Pygoscelis papua: Habe ich noch gar nicht drüber nachgedacht, aber macht ``less`` das denn? Ich wäre jetzt davon ausgegangen, das ``less`` erst den kompletten Inhalt der Datei/Pipe liest und danach erst die Nutzereingaben vom Terminal.

Notfalls schau halt wie ``less`` das macht. Davon gibt's ja den Quelltext.
Sirius3
User
Beiträge: 18264
Registriert: Sonntag 21. Oktober 2012, 17:20

@Pygoscelis papua, BlackJack: neben der Standardeingabe /dev/stdin gibt es auch noch /dev/tty für das Terminal. Da less sowieso direkt mit dem Terminal interagiert ist also noch stdin frei fürs Dateilesen.
Benutzeravatar
noisefloor
User
Beiträge: 4187
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

@blackjack:
macht es nicht, bzw. jedenfalls nicht zwingend. Zitat aus der Man-Page: "Less does not have to read the entire input file before starting,..."

Gruß, noisefloor
Pygoscelis papua
User
Beiträge: 206
Registriert: Freitag 13. März 2015, 18:36

ja ich wusste das less das nicht macht. ich kann ein Programm laufen lassen und mir schon während der Laufzeit die Ausgabe anschauen.
Aber wie mache ich das dann mit dem lesen von /dev/tty? Einfach open('/dev/tty') und dann read... oder wie?

EDIT: Also eine Zeile einlesen like input() geht ja ganz einfach:

Code: Alles auswählen

f = open('/dev/tty')
f.readline()
Aber wenn ich dann wie less ncurses verwende wird es schon schwieriger.
Könnte ich einfach die beiden files "austauschen" in dem ich sage sys.stdin = open('/dev/tty')
und dann um den rest zu lesen einfach open('/dev/stdin').readline() verwende o.ä.?

EDIT2: Also wie es aussieht gerät das Programm dann völlig außer Kontrolle, hier der Quelltext, falls es jemanden interessiert:

Code: Alles auswählen

from curses import wrapper
import sys

sys.stdin = open('/dev/tty')

def main(stdscr):
    while True:
        c = stdscr.getch()
        print(c)
wrapper(main)
und dann im Terminal:

Code: Alles auswählen

echo something|python3 file.py
import this
hidden python features

JAVA = Just Another Vulnerability Announcement :D
Pygoscelis papua
User
Beiträge: 206
Registriert: Freitag 13. März 2015, 18:36

In C++ habe ich rausgefunden wie das geht:

Code: Alles auswählen

int main() {
  signal(SIGINT, sighandler);

  //initscr();
  const char* term_type = getenv("TERM");
  if (term_type == NULL || *term_type == '\0') {
    term_type = "unknown";
  }
  FILE* term_in = fopen("/dev/tty", "r");
  if (term_in == NULL) {
    perror("fopen(/dev/tty)");
    exit(EXIT_FAILURE);
  }
  SCREEN* main_screen = newterm(term_type, stdout, term_in);
  set_term(main_screen);
link dazu:https://www.quora.com/How-can-I-write-a ... e-terminal
bzw.:https://gist.github.com/dreiss/226539

Aber bei dem python curses modul gibt es keine newterm() funktion.

perfekt wäre es, wenn jemand eine gute getch() lösung in python oder so hat, bei der man die input datei einstellen kann, wie
die folgende, welche leider nicht ganz funktioniert:

Code: Alles auswählen

def getch():
    fd = sys.stdin.fileno()
    tty_mode = tty.tcgetattr(fd)
    tty.setcbreak(fd)
    try:
        ch = os.read(fd, 1)
    finally:
            tty.tcsetattr(fd, tty.TCSAFLUSH, tty_mode)
    return ch
Zuletzt geändert von Anonymous am Freitag 24. Juni 2016, 22:38, insgesamt 1-mal geändert.
Grund: Quelltext in Codebox-Tags gesetzt.
import this
hidden python features

JAVA = Just Another Vulnerability Announcement :D
BlackJack

@Pygoscelis papua: Das sieht nach C und nicht C++ aus. :-) Du kannst mit dem Hinweis auf das Problem und diese Lösung ja mal schauen ob Du einen Bug bei Python aufmachen möchtest, dass die das nachrüsten.
Pygoscelis papua
User
Beiträge: 206
Registriert: Freitag 13. März 2015, 18:36

BlackJack hat geschrieben:@Pygoscelis papua: Das sieht nach C und nicht C++ aus. :-)
ja sorry ist doch fast das gleiche, und es war auch schon spät als ich das geschrieben habe. :-)

Eigentlich habe ich keine Lust mich da mit einem Bugbericht rumzuschlagen.
Kann man nicht irgendwie eine getch() funktion von C importieren?
Ich versuche es vieleicht mal.
import this
hidden python features

JAVA = Just Another Vulnerability Announcement :D
Pygoscelis papua
User
Beiträge: 206
Registriert: Freitag 13. März 2015, 18:36

Ich habe gesehen, dass es die getch Bibliothek für python gibt. Ich müsste sie nur noch so umschreiben, dass ich auch damit von '/dev/tty' lesen kann.
import this
hidden python features

JAVA = Just Another Vulnerability Announcement :D
Antworten