Wie bekomme ich die Linux-Konsolenfensterbreite in Python

Gibt es einen Weg in Python, um programmatisch die Breite der Konsole zu bestimmen? Ich meine die Anzahl der Zeichen, die in eine Zeile passt, ohne zu wickeln, nicht die Pixelbreite des Fensters.

Bearbeiten

Auf der Suche nach einer Lösung, die auf Linux funktioniert

14 Solutions collect form web for “Wie bekomme ich die Linux-Konsolenfensterbreite in Python”

 import os rows, columns = os.popen('stty size', 'r').read().split() 

Verwendet die 'stty size' Befehl, die nach einem Thread auf der Python-Mailing-Liste ist relativ universal auf Linux. Es öffnet den Befehl 'stty size' als Datei, 'liest' von ihm und verwendet einen einfachen String Split, um die Koordinaten zu trennen.

Im Gegensatz zu den os.environ ["COLUMNS"] -Wert (die ich trotz der Verwendung von bash nicht als Standard-Shell aufrufen kann) werden die Daten auch aktuell sein, während ich den os.environ ["COLUMNS" Wert wäre nur gültig für die Zeit der Einführung des Python-Interpreters (Angenommen, der Benutzer hat das Fenster seitdem verändert).

Nicht sicher, warum es in der Modul- shutil , aber es landete dort in Python 3.3, Abfrage der Größe des Ausgangs-Terminals :

 >>> import shutil >>> shutil.get_terminal_size((80, 20)) # pass fallback os.terminal_size(columns=87, lines=23) # returns a named-tuple 

Eine Low-Level-Implementierung befindet sich im os-Modul.

Ein Backport ist jetzt für Python 3.2 und unten verfügbar:

benutzen

 import console (width, height) = console.getTerminalSize() print "Your terminal's width is: %d" % width 

EDIT : oh, es tut mir leid. Das ist kein Python-Standard lib eins, hier ist die Quelle der console.py (ich weiß nicht woher es ist).

Das Modul scheint so zu funktionieren: Es prüft, ob termcap verfügbar ist, wenn ja. Das nutzt das; Wenn es nicht prüft, ob das Terminal einen speziellen ioctl Aufruf unterstützt und das auch nicht funktioniert, prüft es auf die Umgebungsvariablen, die einige Shells für diesen exportieren. Dies wird wahrscheinlich nur auf UNIX funktionieren.

 def getTerminalSize(): import os env = os.environ def ioctl_GWINSZ(fd): try: import fcntl, termios, struct, os cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234')) except: return return cr cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2) if not cr: try: fd = os.open(os.ctermid(), os.O_RDONLY) cr = ioctl_GWINSZ(fd) os.close(fd) except: pass if not cr: cr = (env.get('LINES', 25), env.get('COLUMNS', 80)) ### Use get(key[, default]) instead of a try/catch #try: # cr = (env['LINES'], env['COLUMNS']) #except: # cr = (25, 80) return int(cr[1]), int(cr[0]) 

Code oben gab nicht korrektes Ergebnis auf meinem Linux zurück, weil winsize-struct 4 unsigned Shorts hat, nicht 2 signierte Shorts:

 def terminal_size(): import fcntl, termios, struct h, w, hp, wp = struct.unpack('HHHH', fcntl.ioctl(0, termios.TIOCGWINSZ, struct.pack('HHHH', 0, 0, 0, 0))) return w, h 

Hp und hp sollte Pixelbreite und -höhe enthalten, aber nicht.

Ich suchte herum und fand eine Lösung für Fenster an:

http://code.activestate.com/recipes/440694-determine-size-of-console-window-on-windows/

Und eine lösung für linux hier

Also hier ist eine Version, die sowohl auf Linux, os x und windows / cygwin funktioniert:

 """ getTerminalSize() - get width and height of console - works on linux,os x,windows,cygwin(windows) """ __all__=['getTerminalSize'] def getTerminalSize(): import platform current_os = platform.system() tuple_xy=None if current_os == 'Windows': tuple_xy = _getTerminalSize_windows() if tuple_xy is None: tuple_xy = _getTerminalSize_tput() # needed for window's python in cygwin's xterm! if current_os == 'Linux' or current_os == 'Darwin' or current_os.startswith('CYGWIN'): tuple_xy = _getTerminalSize_linux() if tuple_xy is None: print "default" tuple_xy = (80, 25) # default value return tuple_xy def _getTerminalSize_windows(): res=None try: from ctypes import windll, create_string_buffer # stdin handle is -10 # stdout handle is -11 # stderr handle is -12 h = windll.kernel32.GetStdHandle(-12) csbi = create_string_buffer(22) res = windll.kernel32.GetConsoleScreenBufferInfo(h, csbi) except: return None if res: import struct (bufx, bufy, curx, cury, wattr, left, top, right, bottom, maxx, maxy) = struct.unpack("hhhhHhhhhhh", csbi.raw) sizex = right - left + 1 sizey = bottom - top + 1 return sizex, sizey else: return None def _getTerminalSize_tput(): # get terminal width # src: http://stackoverflow.com/questions/263890/how-do-i-find-the-width-height-of-a-terminal-window try: import subprocess proc=subprocess.Popen(["tput", "cols"],stdin=subprocess.PIPE,stdout=subprocess.PIPE) output=proc.communicate(input=None) cols=int(output[0]) proc=subprocess.Popen(["tput", "lines"],stdin=subprocess.PIPE,stdout=subprocess.PIPE) output=proc.communicate(input=None) rows=int(output[0]) return (cols,rows) except: return None def _getTerminalSize_linux(): def ioctl_GWINSZ(fd): try: import fcntl, termios, struct, os cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ,'1234')) except: return None return cr cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2) if not cr: try: fd = os.open(os.ctermid(), os.O_RDONLY) cr = ioctl_GWINSZ(fd) os.close(fd) except: pass if not cr: try: cr = (env['LINES'], env['COLUMNS']) except: return None return int(cr[1]), int(cr[0]) if __name__ == "__main__": sizex,sizey=getTerminalSize() print 'width =',sizex,'height =',sizey 

Beginnend bei Python 3.3 ist es einfach: https://docs.python.org/3/library/os.html#querying-die-size-of-a-terminal

 >>> import os >>> ts = os.get_terminal_size() >>> ts.lines 24 >>> ts.columns 80 

Es sieht so aus, als ob es Probleme mit diesem Code gibt, Johannes:

  • getTerminalSize muss import os
  • Was ist env Sieht aus wie os.environ .

Auch, warum schalten lines und cols vor der Rückkehr? Wenn TIOCGWINSZ und stty beide lines dann cols sagen, sage ich es so. Das verwirrte mich für eine gute 10 Minuten, bevor ich die Inkonsequenz bemerkte.

Sridhar, ich habe diesen Fehler nicht bekommen, als ich die Ausgabe ausgegeben habe. Ich bin mir ziemlich sicher, dass es in der Ausnahme richtig gefangen wird.

Pascal, "HHHH" funktioniert nicht auf meiner Maschine, aber "hh" tut. Ich hatte Schwierigkeiten, eine Dokumentation für diese Funktion zu finden. Es sieht aus wie es plattformabhängig ist.

Chochem, eingebaut.

Hier ist meine Version:

 def getTerminalSize(): """ returns (lines:int, cols:int) """ import os, struct def ioctl_GWINSZ(fd): import fcntl, termios return struct.unpack("hh", fcntl.ioctl(fd, termios.TIOCGWINSZ, "1234")) # try stdin, stdout, stderr for fd in (0, 1, 2): try: return ioctl_GWINSZ(fd) except: pass # try os.ctermid() try: fd = os.open(os.ctermid(), os.O_RDONLY) try: return ioctl_GWINSZ(fd) finally: os.close(fd) except: pass # try `stty size` try: return tuple(int(x) for x in os.popen("stty size", "r").read().split()) except: pass # try environment variables try: return tuple(int(os.getenv(var)) for var in ("LINES", "COLUMNS")) except: pass # i give up. return default. return (25, 80) 

Viele der Python-2-Implementierungen werden hier fehlschlagen, wenn es kein Controlling-Terminal gibt, wenn Sie dieses Skript aufrufen. Sie können überprüfen, sys.stdout.isatty () zu bestimmen, ob dies in der Tat ein Terminal ist, aber das schließt eine Reihe von Fällen, so dass ich glaube, die meisten pythonischen Weg, um herauszufinden, die Terminal-Größe ist es, die builtin curses Paket verwenden.

 import curses w = curses.initscr() height, width = w.getmaxyx() 

Es entweder:

 import os columns, rows = os.get_terminal_size(0) # or import shutil columns, rows = shutil.get_terminal_size() 

Die shutil Funktion ist nur ein Wrapper um os eine, die einige Fehler fängt und ein Fallback, aber es hat eine riesige Einschränkung – es bricht beim Piping! , Was ein ziemlich großes Geschäft ist.
Um die endständige Größe zu erhalten, wenn die Pipeline os.get_terminal_size(0) verwendet wird.

Erstes Argument 0 ist ein Argument, das angibt, dass Stdin-Datei-Deskriptor anstelle von Standard-Stdout verwendet werden soll und wir wollen stdin verwenden, weil sich stdout sich selbst löscht, wenn es geleitet wird und wir einen Fehler bekommen.
Ich habe versucht, herauszufinden, wann wäre es sinnvoll, Stdout statt Stdin Argument verwenden und haben keine Ahnung, warum es ein Standard hier ist.

Ich habe versucht, die Lösung von hier aus, die zu stty size ruft:

 columns = int(subprocess.check_output(['stty', 'size']).split()[1]) 

Das scheiterte aber für mich, weil ich an einem Drehbuch arbeitete, das den umgeleiteten Input auf stdin erwartet, und stty würde sich beschweren, dass "stdin kein Terminal" ist.

Ich konnte es so machen:

 with open('/dev/tty') as tty: height, width = subprocess.check_output(['stty', 'size'], stdin=tty).split() 

Versuche "Segen"

Ich suchte genau das gleiche. Es ist sehr einfach zu bedienen und bietet Werkzeuge zum Färben, Styling und Positionierung im Terminal. Was Sie brauchen, ist so einfach wie:

 from blessings import Terminal t = Terminal() w = t.width h = t.height 

Funktioniert wie ein Charme in Linux. (Ich bin mir nicht sicher über MacOSX und Windows)

Download und Dokumentation hier

Oder Sie können es mit Pip installieren:

 pip install blessings 

Wenn Sie Python 3.3 oder höher verwenden, würde ich das eingebaute get_terminal_size() empfehlen, wie bereits empfohlen. Allerdings, wenn Sie mit einer älteren Version stecken und wollen eine einfache, Cross-Plattform-Weg, dies zu tun, könnten Sie Asciimatics verwenden . Dieses Paket unterstützt Versionen von Python zurück zu 2.7 und verwendet ähnliche Optionen wie oben vorgeschlagen, um die aktuelle Terminal / Konsole Größe zu bekommen.

Erstellen Sie einfach Ihre Screen und verwenden Sie die dimensions , um die Höhe und Breite zu erhalten. Dies hat sich bewährt, um auf Linux, OSX und Windows zu arbeiten.

Oh – und vollständige Offenbarung hier: Ich bin der Autor, also bitte fühlen Sie sich frei, ein neues Problem zu öffnen, wenn Sie irgendwelche Probleme haben, diese zu arbeiten.

Hier ist eine Version, die Linux und Solaris kompatibel sein sollte. Basierend auf den posten und commments von madchine . Benötigt das Teilprozessmodul.

 Def termsize ():
     Importieren shlex, subprocess, re
     Output = subprocess.check_output (shlex.split ('/ bin / stty -a'))
     M = re.search ('Zeilen \ D + (? P \ d +), Spalten \ D + (? P \ d +);', Ausgabe)
     Wenn m:
         Return m.group ('rows'), m.group ('columns')
     OSError erhöhen ('Schlechte Antwort:% s'% (Ausgabe))
 >>> Begriffe ()
 ('40', '100')

@ Reannual's Antwort funktioniert gut, aber es gibt ein Problem damit: os.popen ist jetzt veraltet . Das subprocess Modul sollte stattdessen verwendet werden, also hier ist eine Version von @ reannual's Code, der Unterprozess verwendet und direkt beantwortet die Frage (indem Sie die Spaltenbreite direkt als int :

 import subprocess columns = int(subprocess.check_output(['stty', 'size']).split()[1]) 

Geprüft auf OS X 10.9

  • CPU-Anweisungen nicht mit TensorFlow kompiliert
  • So drucken Sie "Pretty" String Ausgabe in Python
  • Kann ich das Terminal als das aktive Fenster halten, auch wenn es im Hintergrund ist? - Python 3.3
  • Transparente Interaktion mit Konsole (sh, bash, cmd, powershell)
  • UTF8-Stiche im Ubuntu-Terminal mit einem Python-Skript anzeigen
  • So konfigurieren Sie die Anzeigeausgabe in IPython-Pandas
  • Python Multiple Line Terminal Update
  • Wie automatisiert man das Senden von Dateien über das Netzwerk mit python?
  • Halten Sie stdin Linie oben oder unten des Terminalbildschirms
  • Drucken von Unicode-Zeichen in Stdout in Python druckt falsche Glyphen
  • Führen Sie einen Befehl auf Remote Machine in Python aus
  • Python ist die beste Programmiersprache der Welt.