Jak uzyskać szerokość okna konsoli Linuksa w Pythonie
Czy jest sposób w Pythonie aby programowo określić szerokość konsoli? Mam na myśli liczbę znaków, które mieszczą się w jednej linii bez zawijania, a nie Szerokość pikseli okna.
Edit
Szukam rozwiązania, które działa na Linuksie
14 answers
import os
rows, columns = os.popen('stty size', 'r').read().split()
Używa polecenia 'stty size', które zgodnie z wątek na liście dyskusyjnej Pythona jest dość uniwersalny w Linuksie. Otwiera polecenie "rozmiar stty" jako plik, "odczytuje" z niego i używa prostego podziału łańcuchów, aby oddzielić współrzędne.
W przeciwieństwie do os.wartość environ["COLUMNS"] (do której nie mogę uzyskać dostępu pomimo używania Basha jako standardowej powłoki) dane będą również aktualne, podczas gdy wierzę, że system operacyjny.wartość environ["COLUMNS"] będzie ważna tylko przez czas uruchomienie interpretera Pythona (Załóżmy, że od tego czasu użytkownik zmienił rozmiar okna).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-03 10:06:54
Nie wiem, dlaczego jest w module shutil
, ale wylądował tam w Pythonie 3.3, pytając o rozmiar terminala wyjściowego :
>>> import shutil
>>> shutil.get_terminal_size((80, 20)) # pass fallback
os.terminal_size(columns=87, lines=23) # returns a named-tuple
Implementacja niskiego poziomu znajduje się w module systemu operacyjnego.
Backport jest teraz dostępny dla Pythona 3.2 i poniżej:
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-30 17:45:29
Użyj
import console
(width, height) = console.getTerminalSize()
print "Your terminal's width is: %d" % width
EDIT : przepraszam. To nie jest standardowy lib Pythona, oto źródło console.py (Nie wiem skąd pochodzi).
Moduł wydaje się działać w ten sposób: sprawdza, czy termcap
jest dostępny, gdy tak. Używa tego; jeśli nie, sprawdza, czy terminal obsługuje specjalne wywołanie ioctl
i to również nie działa, sprawdza, czy zmienne środowiskowe eksportują do tego niektóre powłoki.
To prawdopodobnie będzie działać tylko na Uniksie.
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])
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-14 19:38:02
Powyższy kod nie zwrócił poprawnego wyniku na moim Linuksie, ponieważ winsize-struct ma 4 unsigned shorts, a nie 2 signed 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 i hp powinny zawierać szerokość i wysokość pikseli, ale nie powinny.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-09 22:36:38
Szukałem i znalazłem rozwiązanie dla windows pod adresem:
Http://code.activestate.com/recipes/440694-determine-size-of-console-window-on-windows/
I rozwiązanie dla Linuksa tutaj.
Oto wersja, która działa zarówno na Linuksie, os x i windows / cygwin:
""" 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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-05 09:22:23
Począwszy od Pythona 3.3 jest prosto: https://docs.python.org/3/library/os.html#querying-the-size-of-a-terminal
>>> import os
>>> ts = os.get_terminal_size()
>>> ts.lines
24
>>> ts.columns
80
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-27 23:24:31
Wygląda na to, że są pewne problemy z tym kodem, Johannes:
-
getTerminalSize
musiimport os
- co to jest
env
? wygląda naos.environ
.
Również, po co przełączać lines
i cols
przed powrotem? Jeśli TIOCGWINSZ
i stty
oba mówią lines
, to cols
, mówię zostawić to w ten sposób. To zdezorientowało mnie przez dobre 10 minut, zanim zauważyłem niespójność.
Sridhar, nie dostałem tego błędu, gdy rurociągiem wyjście. Jestem prawie pewien, że jest dobrze złapany w spróbuj-z wyjątkiem.
Pascal, "HHHH"
nie działa na mojej maszynie, ale "hh"
Działa. Miałem problem ze znalezieniem dokumentacji dla tej funkcji. Wygląda na to, że jest zależny od platformy.
Chochem, incorporated.
Oto moja wersja:
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)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-16 07:23:51
Wiele implementacji Pythona 2 tutaj zawiedzie, jeśli nie ma kontrolującego terminala podczas wywoływania tego skryptu. Możesz sprawdzić sys.stdout.isatty (), aby określić, czy jest to terminal, ale to wyklucza kilka przypadków, więc uważam, że najbardziej pythonicznym sposobem na ustalenie rozmiaru terminala jest użycie wbudowanego pakietu curses.
import curses
w = curses.initscr()
height, width = w.getmaxyx()
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-31 22:26:04
Jest albo:
import os
columns, rows = os.get_terminal_size(0)
# or
import shutil
columns, rows = shutil.get_terminal_size()
Funkcja shutil
jest tylko owijarką wokół os
, która wychwytuje pewne błędy i ustawia rezerwę, jednak ma jedno ogromne zastrzeżenie- pęka podczas orurowania!, co jest całkiem sporą sprawą.
Aby uzyskać rozmiar terminala podczas rurociągu, użyj os.get_terminal_size(0)
.
Pierwszy argument 0
jest argumentem wskazującym, że deskryptor pliku stdin powinien być używany zamiast domyślnego stdout. Chcemy używać stdin, ponieważ stdout odłącza się, gdy jest piped, który podnosi w tym przypadku powoduje błąd..
Próbowałem dowiedzieć się, kiedy ma sens używanie stdout zamiast argumentu stdin i nie mam pojęcia, dlaczego jest to tutaj Domyślne.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-03 04:51:39
[[5]]@re: odpowiedź działa dobrze, ale jest z tym problem: os.popen
jest obecnie przestarzały . Zamiast tego powinien być użyty moduł subprocess
, więc oto wersja kodu @re annual, który używa subprocess
i odpowiada bezpośrednio na pytanie (podając szerokość kolumny bezpośrednio jako int
:
import subprocess
columns = int(subprocess.check_output(['stty', 'size']).split()[1])
Testowane na OS X 10.9
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-22 18:30:16
Próbowałem stąd rozwiązania, które wywołuje stty size
:
columns = int(subprocess.check_output(['stty', 'size']).split()[1])
Jednak nie udało mi się to, ponieważ pracowałem nad skryptem, który oczekuje przekierowanego wejścia na stdin i stty
narzekałbym, że "stdin nie jest terminalem" w tym przypadku.
Udało mi się to zrobić tak:
with open('/dev/tty') as tty:
height, width = subprocess.check_output(['stty', 'size'], stdin=tty).split()
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-08 18:36:32
Try"blessings"
Szukałam tego samego. Jest bardzo łatwy w użyciu i oferuje narzędzia do kolorowania, stylizacji i pozycjonowania w terminalu. To, czego potrzebujesz, jest tak proste, jak:from blessings import Terminal
t = Terminal()
w = t.width
h = t.height
Działa jak urok w Linuksie. (Nie jestem pewien co do MacOSX i Windows)
Pobierz i dokumentację tutaj
Lub możesz go zainstalować za pomocą pip:
pip install blessings
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-23 12:00:41
Jeśli używasz Pythona 3.3 lub nowszego, polecam wbudowany get_terminal_size()
jako już zalecany. Jeśli jednak utknąłeś w starszej wersji i chcesz zrobić to w prosty, wieloplatformowy sposób, możesz użyć asciimatics. Ten pakiet obsługuje wersje Pythona z powrotem do 2.7 i używa podobnych opcji do tych sugerowanych powyżej, aby uzyskać bieżący rozmiar terminala / konsoli.
Po prostu zbuduj klasę Screen
i użyj właściwości dimensions
, aby uzyskać wysokość i szerokość. To ma udowodniono, że działa na Linuksie, OSX i Windows.
Oh-i pełne ujawnienie tutaj: jestem autorem, więc proszę, nie krępuj się otworzyć nowy numer, jeśli masz jakiekolwiek problemy z doprowadzeniem tego do pracy.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-24 09:54:50
Oto wersja, która powinna być kompatybilna z Linuksem i Solarisem. Na podstawie postów i komentarzy z madchine . Wymaga modułu podprocesu.
def termsize(): import shlex, subprocess, re output = subprocess.check_output(shlex.split('/bin/stty -a')) m = re.search('rows\D+(?P\d+); columns\D+(?P\d+);', output) if m: return m.group('rows'), m.group('columns') raise OSError('Bad response: %s' % (output))
>>> termsize() ('40', '100')
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:55:19