파이썬에서 콘솔의 너비를 프로그래밍 방식으로 결정하는 방법이 있습니까? 나는 창의 픽셀 너비가 아니라 줄 바꿈없이 한 줄에 맞는 문자 수를 의미합니다.
편집하다
Linux에서 작동하는 솔루션을 찾고
파이썬에서 콘솔의 너비를 프로그래밍 방식으로 결정하는 방법이 있습니까? 나는 창의 픽셀 너비가 아니라 줄 바꿈없이 한 줄에 맞는 문자 수를 의미합니다.
편집하다
Linux에서 작동하는 솔루션을 찾고
답변:
import os
rows, columns = os.popen('stty size', 'r').read().split()
파이썬 메일 링리스트의 스레드에 따라 'stty size'명령을 사용합니다 . 리눅스에서는 합리적입니다. 'stty size'명령을 파일로 열고 파일에서 읽은 다음 간단한 문자열 분할을 사용하여 좌표를 구분합니다.
os.environ [ "COLUMNS"] 값과 달리 (표준 쉘로 bash를 사용하더라도 액세스 할 수 없음) 데이터도 최신 상태이지만 os.environ [ "COLUMNS"] 값은 파이썬 인터프리터가 시작된 시간에만 유효합니다 (그 이후로 사용자가 창 크기를 조정했다고 가정하십시오).
(python 3.3 이상 에서이 작업을 수행하는 방법에 대한 @GringoSuave의 답변 참조)
rows, columns = subprocess.check_output(['stty', 'size']).split()
조금 짧은 플러스 서브 프로세스는 미래입니다
rows, columns = subprocess.check_output(['stty', 'size']).decode().split()
py2 / 3 호환성을위한 유니 코드 문자열을 원한다면
왜 모듈에 있는지 shutil
모르지만 파이썬 3.3에 도착 하여 출력 터미널의 크기를 쿼리합니다 .
>>> import shutil
>>> shutil.get_terminal_size((80, 20)) # pass fallback
os.terminal_size(columns=87, lines=23) # returns a named-tuple
저수준 구현은 os 모듈에 있습니다. Windows에서도 작동합니다.
백 포트는 이제 Python 3.2 이하에서 사용 가능합니다 :
python3.5
설치되었습니다.
Inappropriate ioctl for device
오류 / 경고 가 발생하거나 정의 된 폴백 값 80을
사용하다
import console
(width, height) = console.getTerminalSize()
print "Your terminal's width is: %d" % width
편집 : 아, 죄송합니다. 그것은 파이썬 표준 라이브러리가 아닙니다. 여기서 console.py 소스가 있습니다 (어디에서 왔는지 모르겠습니다).
모듈은 다음과 같이 작동하는 것 같습니다 termcap
. 사용 가능한 경우 사용 가능한지 확인합니다 . 그것을 사용합니다. 그렇지 않으면 터미널이 특수 ioctl
호출을 지원하는지 여부 와 작동하지 않는지 확인하고 일부 쉘이 내보내는 환경 변수를 확인합니다. 이것은 아마도 UNIX에서만 작동합니다.
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])
winsize-struct에는 2 개의 부호있는 반바지가 아닌 4 개의 부호없는 반바지가 있기 때문에 위의 코드는 Linux에서 올바른 결과를 반환하지 않았습니다.
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와 hp는 픽셀 너비와 높이를 포함해야하지만 그렇지 않습니다.
fcntl.ioctl(sys.stdin.fileno(), ...
stdout
또는 stderr
대신에 사용해야한다고 생각합니다 stdin
. stdin
파이프 일 수도 있습니다. 과 같은 줄을 추가 할 수도 있습니다 if not os.isatty(0): return float("inf")
.
나는 주변에서 검색하고 창문에 대한 해결책을 찾았습니다.
http://code.activestate.com/recipes/440694-determine-size-of-console-window-on-windows/
여기에 리눅스 솔루션이 있습니다.
linux, os x 및 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
다음 중 하나입니다.
import os
columns, rows = os.get_terminal_size(0)
# or
import shutil
columns, rows = shutil.get_terminal_size()
이 shutil
기능은 os
약간의 오류를 포착하고 폴백을 설정 하는 래퍼입니다 . 그러나 한 가지 큰 경고가 있습니다 . , 이것은 꽤 큰 거래입니다.
배관시 터미널 크기를 얻으려면 os.get_terminal_size(0)
대신 사용하십시오.
첫 번째 주장 0
는 기본 stdout 대신 stdin 파일 디스크립터를 사용해야 함을 나타내는 입니다. stdin이 파이프 될 때 자체가 분리 되어이 경우 오류가 발생하기 때문에 stdin을 사용하려고합니다.
나는 stdin 인수 대신 stdout을 사용하는 것이 언제 의미가 있는지 알아 내려고 왜 이것이 기본값인지 알지 못했습니다.
os.get_terminal_size()
Python 3.3에서 소개되었습니다
os.get_terminal_size(0)
stdin으로 파이프 하면 사용 이 중단됩니다. 시도 :echo x | python3 -c 'import os; print(os.get_terminal_size(0))'
Python 3.3부터는 다음과 같이 간단합니다. 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
shutil.get_terminal_size() is the high-level function which should normally be used, os.get_terminal_size is the low-level implementation.
해당 코드에 문제가있는 것 같습니다 (요하네스).
getTerminalSize
할 필요가있다 import os
env
입니까? 처럼 보인다 os.environ
.또한, 왜 전환 lines
및 cols
반환하기 전에? 경우 TIOCGWINSZ
와 stty
두 말을 lines
한 후 cols
, 나는 그런 식으로 떠나 말한다. 불일치를 발견하기 전에 10 분 동안 혼란 스러웠습니다.
Sridhar, 출력을 파이프 할 때 그 오류가 발생하지 않았습니다. 시험 제외에서 제대로 잡히고 있다고 확신합니다.
파스칼, "HHHH"
내 컴퓨터에서 작동하지 않지만 작동합니다 "hh"
. 해당 기능에 대한 설명서를 찾는 데 문제가있었습니다. 플랫폼에 따라 다릅니다.
chochem, 통합됨.
내 버전은 다음과 같습니다.
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)
나는 여기에서 부르는 해결책을 시도했다 stty size
.
columns = int(subprocess.check_output(['stty', 'size']).split()[1])
그러나 stdin에서 리디렉션 된 입력을 예상하는 스크립트를 작업하고 있었기 때문에 이것은 실패했습니다. stty
.이 경우 "stdin은 터미널이 아닙니다".
나는 다음과 같이 작동시킬 수있었습니다.
with open('/dev/tty') as tty:
height, width = subprocess.check_output(['stty', 'size'], stdin=tty).split()
"축복"을 보십시오
나는 똑같은 것을 찾고있었습니다. 사용하기 매우 쉽고 터미널에서 색상, 스타일 및 위치 지정 도구를 제공합니다. 필요한 것은 다음과 같습니다.
from blessings import Terminal
t = Terminal()
w = t.width
h = t.height
리눅스에서 매력처럼 작동합니다. (MacOSX와 Windows에 대해 잘 모르겠습니다)
여기에서 다운로드 및 설명서
또는 pip로 설치할 수 있습니다.
pip install blessings
@reannual의 답변은 잘 작동하지만 문제가 있습니다 : os.popen
이제 더 이상 사용되지 않습니다 . subprocess
모듈은 그래서 여기에 사용하는 @ reannual의 코드의 버전입니다, 대신 사용해야합니다 subprocess
직접가로 직접 열 너비를 제공하여 (질문에 대한 답은 int
:
import subprocess
columns = int(subprocess.check_output(['stty', 'size']).split()[1])
OS X 10.9에서 테스트
Python 3.3 이상을 사용하는 경우 내장 get_terminal_size()
권장 사항을 이미 권장합니다. 그러나 이전 버전을 사용하고 있고이를 수행하는 간단한 크로스 플랫폼 방식을 원할 경우 비산 법을 사용할 수 있습니다 . 이 패키지는 2.7로 돌아가는 Python 버전을 지원하며 위에 제시된 것과 유사한 옵션을 사용하여 현재 터미널 / 콘솔 크기를 얻습니다.
Screen
클래스를 구성 하고 dimensions
속성을 사용 하여 높이와 너비를 얻으십시오. 이것은 Linux, OSX 및 Windows에서 작동하는 것으로 입증되었습니다.
아-그리고 여기에 전체 공개 : 나는 저자이므로,이 문제를 해결하는 데 문제가 있으면 언제든지 새로운 문제를여십시오.
다음은 Linux 및 Solaris 호환 버전이어야합니다. 에서 게시물과 commments을 바탕으로 madchine . 서브 프로세스 모듈이 필요합니다.
데프 termize () : shlex, 하위 프로세스 가져 오기, 다시 가져 오기 출력 = subprocess.check_output (shlex.split ( '/ bin / stty -a')) m = re.search ( 'rows \ D + (? P \ d +); columns \ D + (? P \ d +);', 출력) m 인 경우 : m.group ( 'rows'), m.group ( 'columns') 반환 OSError 발생 ( '잘못된 응답 : % s'% (출력))
>>> termsize () ( '40', '100')