source

Python에서 Linux 콘솔 창 너비를 가져오는 방법

factcode 2023. 1. 19. 21:00
반응형

Python에서 Linux 콘솔 창 너비를 가져오는 방법

python에서 콘솔의 폭을 프로그래밍 방식으로 결정할 수 있는 방법이 있나요?윈도우의 픽셀 너비가 아니라 래핑하지 않고 한 줄에 들어가는 글자 수를 말합니다.

편집

Linux에서 동작하는 솔루션을 찾고 있다

안에 알 수 .shutilPython 3.3 python python python python python python python python python python 。

출력 단자 크기 쿼리

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

OS 모듈에는 낮은 수준의 구현이 포함되어 있습니다.크로스 플랫폼: Linux, Mac OS 및 Windows, 아마도 다른 Unix-likes에서 작동합니다.더 이상 관련이 없지만 백포트도 있습니다.

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

는 python 메일목록의 스레드에 따라 Linux에서 합리적으로 보편적인 'stty size' 명령어를 사용합니다.stty size 명령어를 파일로 열고 여기서 '읽기'하며 간단한 문자열 분할을 사용하여 좌표를 구분합니다.

os.environment와 달리 ["COLUMNS"] 값(bash를 표준 쉘로 사용해도 액세스할 수 없음)도 os.environment["라고 생각합니다.COLUMNS"] 값은 python interpreter 실행 시에만 유효합니다(그 이후 사용자가 창의 크기를 조정한 경우).

(python 3.3+에서 이 작업을 수행하는 방법에 대해서는 @GringoSuave의 답변을 참조하십시오.)

사용하다

import console
(width, height) = console.getTerminalSize()

print "Your terminal's width is: %d" % width

편집: 아, 죄송합니다.python standard lib가 아니라 console.py의 소스입니다(출처는 모르겠습니다).

모듈은 다음과 같이 동작합니다.「 」의 유무를 합니다.termcap사용가능합니다. 명령어는 그것을 사용합니다.아니오인 한 지원 합니다.아니오일 경우 단말기가 특별한 기능을 지원하는지 여부를 체크합니다.ioctl이를 합니다.call 을 호출합니다.일부 셸이 이를 위해 내보내는 환경변수를 체크합니다.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는 픽셀 폭과 높이를 포함해야 하지만 포함하지 않습니다.

다음 중 하나입니다.

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은 stdout을 합니다.

stdin 인수 대신 stdout을 사용하는 것이 언제 의미가 있는지 알아보려고 노력했지만, 왜 이것이 기본값인지 알 수 없습니다.

검색해 보니, 다음의 에 있는 Windows 의 솔루션이 있었습니다.

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

Linux 용 솔루션이 여기에 있습니다.

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

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

이 코드에는 몇 가지 문제가 있는 것 같습니다.요하네스:

  • getTerminalSize 가 있다import os
  • 가 뭐죠?env ?아니다.os.environ.

스위치 「」, 「」의 이기도 합니다.lines ★★★★★★★★★★★★★★★★★」cols★★★★★★★★★★★★★★★★★? ifTIOCGWINSZ ★★★★★★★★★★★★★★★★★」stty 다 말하다linescols스러워서 부정합이 .이것은 모순을 알아차리기 전에 10분 동안 나를 혼란스럽게 했다.

스리다르, 출력을 파이프로 연결했을 때 오류가 안 났는데시험만 빼고 잘 잡혔을 거야

스칼,,"HHHH"하지 않지만, ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★」"hh"네, 그 기능에 대한 문서를 찾는 데 어려움을 겪었습니다.이치노

화학, 주식회사

내 버전은 다음과 같습니다.

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)

이 스크립트를 호출할 때 제어 단말기가 없으면 여기에 있는 Python 2 구현의 대부분은 실패합니다.sys.stdout.isatty()를 체크하여 이것이 실제로 단말기인지 아닌지를 판단할 수 있습니다.단말기 사이즈를 알 수 있는 가장 기본적인 방법은 내장된 저주 패키지를 사용하는 것이라고 생각합니다.

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

"축복"을 받으십시오.

나도 똑같은 걸 찾고 있었어매우 사용하기 쉽고 터미널에 색칠, 스타일링 및 위치 설정을 위한 도구를 제공합니다.필요한 것은 다음과 같이 간단합니다.

from blessings import Terminal

t = Terminal()

w = t.width
h = t.height

Linux에서는 매력적으로 동작합니다.(MacOSX나 Windows는 잘 모르겠습니다)

다운로드 및 매뉴얼은 이쪽

또는 pip을 사용하여 설치할 수 있습니다.

pip install blessings

는 서부터 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★stty size:

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

및 입력을 를 작성하고 때문에 이 했습니다.stty'스틴은 단말기가 아니다'라고 불평할 겁니다.

이렇게 할 수 있었습니다.

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

Python 3.3 또는 그 이상을 사용하시는 경우, 빌트인을 추천합니다.get_terminal_size()이미 권장된 대로입니다.다만, 구버전을 고집하고 있어, 심플하고 크로스 플랫폼의 방법을 원한다면, asciamatics를 사용할 수 있습니다.이 패키지는 Python의 2.7 버전을 지원하며 현재 터미널/콘솔 크기를 얻기 위해 위에서 제시한 것과 유사한 옵션을 사용합니다.

심플하게 구성하면Screenclass 및 를 사용합니다.dimensions높이와 폭을 가져오는 속성입니다.Linux, OSX 및 Windows에서 동작하는 것이 실증되었습니다.

아, 그리고 여기 완전 공개: 제가 저자이기 때문에, 만약 이것이 작동하는데 문제가 있다면 언제든지 새로운 호를 개설해 주십시오.

@reyearnal의 답변은 올바르게 기능하지만 다음과 같은 문제가 있습니다.os.popen 는 폐지되었습니다.subprocess대신 모듈을 사용해야 합니다.따라서 @renearnal 코드 버전은 다음과 같습니다.subprocess (열를 (열 너비로) 직접 합니다.int:

import subprocess

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

OS X 10.9에서 테스트 완료

다음은 Linux 및 Solaris와 호환되는 버전입니다.매딘의 글과 댓글을 근거로 합니다.하위 프로세스 모듈이 필요합니다.

def termsize():
Import, shlex, 서브프로세스, reoutput = 하위 프로세스입니다.check_output(shlex.syslog/bin/stty -a')m = re.search('rows\D+'(?)P\d+; 컬럼\D+(?)P\d+;', 출력)m:m.group'rows'), m.group's'를 반환한다.OSError('오답: %s' % (출력))를 올립니다.
용어집()('40', '100')

언급URL : https://stackoverflow.com/questions/566746/how-to-get-linux-console-window-width-in-python

반응형