Seite 1 von 1
less mit python
Verfasst: Freitag 24. Juni 2016, 11:08
von Pygoscelis papua
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?
Re: less mit python
Verfasst: Freitag 24. Juni 2016, 19:36
von 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.
Re: less mit python
Verfasst: Freitag 24. Juni 2016, 19:53
von Sirius3
@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.
Re: less mit python
Verfasst: Freitag 24. Juni 2016, 19:56
von noisefloor
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
Re: less mit python
Verfasst: Freitag 24. Juni 2016, 20:17
von Pygoscelis papua
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:
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:
Re: less mit python
Verfasst: Freitag 24. Juni 2016, 21:06
von Pygoscelis papua
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
Re: less mit python
Verfasst: Freitag 24. Juni 2016, 22:37
von 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.
Re: less mit python
Verfasst: Samstag 25. Juni 2016, 06:14
von Pygoscelis papua
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.
Re: less mit python
Verfasst: Samstag 25. Juni 2016, 21:08
von Pygoscelis papua
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.