Re: get the terminal's size
> On Mon, 14 Jan 2019 11:57:33 +, Alex Ternaute wrote: > > > Hi there, > > > > I want to know the number of columns of the terminal where python2 writes > > it's outputs. A couple days late to the party, a discussion of several ways I tried: http://shallowsky.com/blog/hardware/serial-24-line-terminals.html and the script I ended up with: https://github.com/akkana/scripts/blob/master/termsize (I've only tested these on Linux). ...Akkana -- https://mail.python.org/mailman/listinfo/python-list
Re: get the terminal's size
On Mon, 14 Jan 2019 11:57:33 +, Alex Ternaute wrote: > Hi there, > > I want to know the number of columns of the terminal where python2 writes > it's outputs. > > In a terminal, I type > $ echo $COLUMNS > 100 > > But in Python, os.getenv("COLUMNS") gets nothing. > It gets nothing as well if I try to read the output of "echo $COLUMNS" > from a subprocess. > > I feel that I'm missing something but what ? > > Looking on the internet for a hint, I see that python3 has an > os.get_terminal_size(). > Please, is there something similar for python2 ? > > Cheers I have used this Python2 code with success in Linux... #!/usr/bin/env python import fcntl import os import struct import termios tty = os.open(os.ctermid(), os.O_RDONLY) ts = struct.unpack("hh", fcntl.ioctl(tty, termios.TIOCGWINSZ, "1234")) os.close(tty) print str(ts[1]) + "x" + str(ts[0]) -- GNU/Linux user #557453 "There are only 10 types of people in the world... those who understand Binary and those who don't." -Spike -- https://mail.python.org/mailman/listinfo/python-list
Re: get the terminal's size
On 2019-01-16, Karen Shaeffer wrote: [fixed quoting and formatting] >> That will tell you the terminal size at the time Python was started. >> >> If the terminal size has changed while Python was running, those >> environment variables will be wrong. You need to use the TIOCGWINSZ >> ioctl call: >> >> http://www.delorie.com/djgpp/doc/libc/libc_495.html >> >> And to detect the size changes (so you know _when_ you need to do the >> above), you need to attach a signal handler for the WINCH signal. > > I'm running a python 3 interpreter on linux. I'm actually ssh'd into > the terminal on a headless server. [...] > [...] > With the python interpreter running on the remote terminal, I have > resized the terminal window on my local laptop several times. And > each time, the remote python interpreter knows about the change, > correctly printing the new size. I have done nothing with > environment variables. I have not used a signal handler for the > WINCH signal. It just works. Yes, we know that works on Python3. The discussion was about what to do on Python2. $ python2 Python 2.7.15 (default, Sep 12 2018, 15:19:18) [GCC 7.3.0] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import shutil >>> shutil.get_terminal_size() Traceback (most recent call last): File "", line 1, in AttributeError: 'module' object has no attribute 'get_terminal_size' >>> -- Grant Edwards grant.b.edwardsYow! I'm having a BIG BANG at THEORY!! gmail.com -- https://mail.python.org/mailman/listinfo/python-list
Re: get the terminal's size
That will tell you the terminal size at the time Python was started. If the terminal size has changed while Python was running, those environment variables will be wrong. You need to use the TIOCGWINSZ ioctl call: http://www.delorie.com/djgpp/doc/libc/libc_495.html And to detect the size changes (so you know _when_ you need to do the above), you need to attach a signal handler for the WINCH signal. Hi, I'm running a python 3 interpreter on linux. I'm actually ssh'd into the terminal on a headless server. And so my terminal is my local laptop terminal window, with the python interpreter running on the remote linux box terminal, communicating over an ssh connection. $ python3 Python 3.6.7 (default, Oct 22 2018, 11:32:17) [GCC 8.2.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import shutil >>> print(f"{shutil.get_terminal_size()}\n") os.terminal_size(columns=118, lines=63) >>> print(f"{shutil.get_terminal_size()}\n") os.terminal_size(columns=133, lines=63) >>> print(f"{shutil.get_terminal_size()}\n") os.terminal_size(columns=118, lines=65) >>> print(f"{shutil.get_terminal_size()}\n") os.terminal_size(columns=118, lines=63) With the python interpreter running on the remote terminal, I have resized the terminal window on my local laptop several times. And each time, the remote python interpreter knows about the change, correctly printing the new size. I have done nothing with environment variables. I have not used a signal handler for the WINCH signal. It just works. Karen. -- https://mail.python.org/mailman/listinfo/python-list
Re: get the terminal's size
On 15Jan2019 13:08, Alex Ternaute wrote: I tried : P = Popen(['stty', '-a'], stdout=subprocess.PIPE, universal_newlines=True) and it runs fine too, so the output seems not really related to that fd. But it is! stty(1) fetches the terminal settings from its standard input, so "fd" is used to supply this. In your Popen test case you simply don't set the stdin parameter, so it is the Python process' input. Which is usually what you want. But I want to be able to ask this of any terminal file, thus the parameter. Ah, Ok; smthlike: cs.tty.ttysize(0) WinSize(rows=50, columns=100) anotherTty=open('/dev/pts/3', 'rw') cs.tty.ttysize(anotherTty) WinSize(rows=43, columns=199) It runs :) Exactly so. BTW, you're aware of: from cs.tty import ttysize ... ttysize(0) I presume, and the above is just your testing? Cheers, Cameron Simpson -- https://mail.python.org/mailman/listinfo/python-list
Re: get the terminal's size
Hi Cameron, >>I tried : P = Popen(['stty', '-a'], stdout=subprocess.PIPE, >>universal_newlines=True) and it runs fine too, so the output seems not >>really related to that fd. > But it is! stty(1) fetches the terminal settings from its standard > input, so "fd" is used to supply this. In your Popen test case you > simply don't set the stdin parameter, so it is the Python process' > input. Which is usually what you want. > But I want to be able to ask this > of any terminal file, thus the parameter. Ah, Ok; smthlike: cs.tty.ttysize(0) WinSize(rows=50, columns=100) anotherTty=open('/dev/pts/3', 'rw') cs.tty.ttysize(anotherTty) WinSize(rows=43, columns=199) It runs :) I do not need that today but one day orother it could help. Cheers -- Alex -- https://mail.python.org/mailman/listinfo/python-list
Re: get the terminal's size
On 15Jan2019 10:26, Alex Ternaute wrote: My cs.tty module (on PyPI) has a ttysize function: https://pypi.org/project/cs.tty/ which just parses the output of the stty command. [...] Fine, indeed ! I've installed cs.ttyy. I just don't understand the reason why it takes "fd" as an argument. "fd" may be a file descriptor or a file (from which it gets the underlying fd). I tried : P = Popen(['stty', '-a'], stdout=subprocess.PIPE, universal_newlines=True) and it runs fine too, so the output seems not really related to that fd. But it is! stty(1) fetches the terminal settings from its standard input, so "fd" is used to supply this. In your Popen test case you simply don't set the stdin parameter, so it is the Python process' input. Which is usually what you want. But I want to be able to ask this of any terminal file, thus the parameter. Just pass 0 to ttysize, or sys.stdin. Arguably that should be a default value. Btw I did not know about namedtuple, thanks for that too. Yes, it is very handy. Cheers, Cameron Simpson -- https://mail.python.org/mailman/listinfo/python-list
Re: get the terminal's size
Hi thereĀ : > On 2019-01-14, Bob van der Poel wrote: >> http://stackoverflow.com/questions/566746/how-to-get-console-window- width-in-python Simple and direct, I think I'll use this one. Thanks a lot. John Doe : > and have a look at this one too: > https://stackoverflow.com/questions/1396820/apt-like-column-output- python-library/1446973#1446973 Fine, but It meets much more needs than my present one. But thanks too. Bye -- Alex -- https://mail.python.org/mailman/listinfo/python-list
Re: get the terminal's size
Hi Cameron, > My cs.tty module (on PyPI) has a ttysize function: > https://pypi.org/project/cs.tty/ > which just parses the output of the stty command. > If you don't want the cs.tty module, the ttysize code is just this: > > WinSize = namedtuple('WinSize', 'rows columns') > > def ttysize(fd): > ''' Return a (rows, columns) tuple for the specified file > descriptor. > [...] Fine, indeed ! I've installed cs.ttyy. I just don't understand the reason why it takes "fd" as an argument. I tried : P = Popen(['stty', '-a'], stdout=subprocess.PIPE, universal_newlines=True) and it runs fine too, so the output seems not really related to that fd. Btw I did not know about namedtuple, thanks for that too. > Hope this helps. Greatly. Cheers, -- Alex -- https://mail.python.org/mailman/listinfo/python-list
Re: get the terminal's size
On 1/14/19, Schachner, Joseph wrote: > I just tested the fix I proposed, in Python 2.7.13 > > Code: > from win32api import GetSystemMetrics > > def main(): > print "Width =", GetSystemMetrics(0) > print "Height =", GetSystemMetrics(1) That gets the monitor size, i.e: SM_CXSCREEN (0) The width of the screen of the primary display monitor, in pixels. SM_CYSCREEN (1) The height of the screen of the primary display monitor, in pixels. The console's visible window is a rectangular view on its active screen buffer. We have to query the screen-buffer information to obtain the coordinates of this rectangle (right, left, bottom, top). Python's os.get_terminal_size does this, but I dislike the fact that it uses the process standard handles instead of C file descriptors and only supports 0, 1, and 2. Here's a version that defaults to opening the console's active screen buffer, "CONOUT$". Otherwise it uses msvcrt.get_osfhandle to get the handle for the fd argument instead of hard-mapping 0, 1, and 2 to the process standard handles. For symmetry, I've also added POSIX code that switches the default to opening "/dev/tty" instead of using stdout. import os import ctypes from collections import namedtuple terminal_size = namedtuple('terminal_size', 'columns lines') if os.name == 'posix': import tty import fcntl class winsize(ctypes.Structure): _fields_ = (('ws_row', ctypes.c_ushort), ('ws_col', ctypes.c_ushort), ('ws_xpixel', ctypes.c_ushort), ('ws_ypixel', ctypes.c_ushort)) def get_terminal_size(fd=None): """Return the size of the terminal window as (columns, lines). The optional argument fd specifies which file descriptor should be queried. An OSError is raised if the file descriptor is not connected to a terminal (Unix) or a console screen buffer (Windows). The default behavior is to open and query the process controlling terminal (i.e. Unix "/dev/tty") or active console screen buffer (i.e. Windows "CONOUT$"). """ w = winsize() if fd is None: fd_used = os.open('/dev/tty', os.O_RDWR) else: fd_used = fd try: fcntl.ioctl(fd_used, tty.TIOCGWINSZ, w) finally: if fd is None: os.close(fd_used) return terminal_size(w.ws_col, w.ws_row) elif os.name == 'nt': import msvcrt from ctypes import wintypes kernel32 = ctypes.WinDLL('kernel32', use_last_error=True) class CONSOLE_SCREEN_BUFFER_INFO(ctypes.Structure): _fields_ = (('dwSize', wintypes._COORD), ('dwCursorPosition', wintypes._COORD), ('wAttributes', wintypes.WORD), ('srWindow', wintypes.SMALL_RECT), ('dwMaximumWindowSize', wintypes._COORD)) kernel32.GetConsoleScreenBufferInfo.argtypes = ( wintypes.HANDLE, ctypes.POINTER(CONSOLE_SCREEN_BUFFER_INFO)) def get_terminal_size(fd=None): """Return the size of the terminal window as (columns, lines). The optional argument fd specifies which file descriptor should be queried. An OSError is raised if the file descriptor is not connected to a terminal (Unix) or a console screen buffer (Windows). The default behavior is to open and query the process controlling terminal (i.e. Unix "/dev/tty") or active console screen buffer (i.e. Windows "CONOUT$"). """ csbi = CONSOLE_SCREEN_BUFFER_INFO() w = csbi.srWindow if fd is None: fd_used = os.open('CONOUT$', os.O_RDWR) else: fd_used = fd try: h = msvcrt.get_osfhandle(fd_used) if not kernel32.GetConsoleScreenBufferInfo(h, ctypes.byref(csbi)): raise ctypes.WinError(ctypes.get_last_error()) finally: if fd is None: os.close(fd_used) return terminal_size(w.Right - w.Left + 1, w.Bottom - w.Top + 1) -- https://mail.python.org/mailman/listinfo/python-list
Re: get the terminal's size
On 2019-01-14, Bob van der Poel wrote: > try this: > > > http://stackoverflow.com/questions/566746/how-to-get-console-window-width-in-python > and have a look at this one too: https://stackoverflow.com/questions/1396820/apt-like-column-output-python-library/1446973#1446973 > -- https://mail.python.org/mailman/listinfo/python-list
Re: get the terminal's size
On 14Jan2019 17:16, Alex Ternaute wrote: Looking on the internet for a hint, I see that python3 has an os.get_terminal_size(). Use that then. Up to now I wanted to keep compatibility with a big bunch of code in Python2 that I do no maintain by myself. Well, I saw that get_terminal_size() follows the windows resizings. Whenever I consider forking to Python3, this would be my 1st step. Please, is there something similar for python2 ? I suspect there is some solution in the curses module... I did dir(curse) but I could not see if something goes this way. My cs.tty module (on PyPI) has a ttysize function: https://pypi.org/project/cs.tty/ which just parses the output of the stty command. Personally I resist using the environment variables; they're (a) not exports by default because they're "live" and (b) then don't track changes if they are exported and (c) rely on the shell providing them. I just don't trust them. If you don't want the cs.tty module, the ttysize code is just this: WinSize = namedtuple('WinSize', 'rows columns') def ttysize(fd): ''' Return a (rows, columns) tuple for the specified file descriptor. If the window size cannot be determined, None will be returned for either or both of rows and columns. This function relies on the UNIX `stty` command. ''' if not isinstance(fd, int): fd = fd.fileno() P = Popen(['stty', '-a'], stdin=fd, stdout=PIPE, universal_newlines=True) stty = P.stdout.read() xit = P.wait() if xit != 0: return None m = re.compile(r' rows (\d+); columns (\d+)').search(stty) if m: rows, columns = int(m.group(1)), int(m.group(2)) else: m = re.compile(r' (\d+) rows; (\d+) columns').search(stty) if m: rows, columns = int(m.group(1)), int(m.group(2)) else: rows, columns = None, None return WinSize(rows, columns) Hope this helps. Cheers, Cameron Simpson -- https://mail.python.org/mailman/listinfo/python-list
Re: get the terminal's size
On Mon, Jan 14, 2019 at 4:57 AM Alex Ternaute wrote: > Hi there, > > I want to know the number of columns of the terminal where python2 writes > it's outputs. > > In a terminal, I type > $ echo $COLUMNS > 100 > > But in Python, os.getenv("COLUMNS") gets nothing. > It gets nothing as well if I try to read the output of "echo $COLUMNS" > from a subprocess. > > I feel that I'm missing something but what ? > > Looking on the internet for a hint, I see that python3 has an > os.get_terminal_size(). > Please, is there something similar for python2 ? > > Cheers > -- > Alex > -- > https://mail.python.org/mailman/listinfo/python-list > try this: http://stackoverflow.com/questions/566746/how-to-get-console-window-width-in-python -- Listen to my FREE CD at http://www.mellowood.ca/music/cedars Bob van der Poel ** Wynndel, British Columbia, CANADA ** EMAIL: b...@mellowood.ca WWW: http://www.mellowood.ca -- https://mail.python.org/mailman/listinfo/python-list
RE: get the terminal's size
I just tested the fix I proposed, in Python 2.7.13 Code: from win32api import GetSystemMetrics def main(): print "Width =", GetSystemMetrics(0) print "Height =", GetSystemMetrics(1) if __name__ == '__main__': main() Result: Width = 1536 Height = 864 -Original Message- From: Alex Ternaute Sent: Monday, January 14, 2019 6:58 AM To: python-list@python.org Subject: get the terminal's size Hi there, I want to know the number of columns of the terminal where python2 writes it's outputs. In a terminal, I type $ echo $COLUMNS 100 But in Python, os.getenv("COLUMNS") gets nothing. It gets nothing as well if I try to read the output of "echo $COLUMNS" from a subprocess. I feel that I'm missing something but what ? Looking on the internet for a hint, I see that python3 has an os.get_terminal_size(). Please, is there something similar for python2 ? Cheers -- Alex -- https://mail.python.org/mailman/listinfo/python-list
Re: get the terminal's size
On 2019-01-14, Schachner, Joseph wrote: > Note sure why you couldn't capture $ echo $COLUMNS from a subprocess > call. You can. But, the subprocess is going to inherit the value from the Python program's environment, so it's just pointless complexity. -- Grant Edwards grant.b.edwardsYow! I represent a at sardine!! gmail.com -- https://mail.python.org/mailman/listinfo/python-list
RE: get the terminal's size
Note sure why you couldn't capture $ echo $COLUMNS from a subprocess call. But, how about this (found on the web): from win32api import GetSystemMetrics print "Width =", GetSystemMetrics(0) print "Height =", GetSystemMetrics(1) -Original Message- From: Alex Ternaute Sent: Monday, January 14, 2019 6:58 AM To: python-list@python.org Subject: get the terminal's size Hi there, I want to know the number of columns of the terminal where python2 writes it's outputs. In a terminal, I type $ echo $COLUMNS 100 But in Python, os.getenv("COLUMNS") gets nothing. It gets nothing as well if I try to read the output of "echo $COLUMNS" from a subprocess. I feel that I'm missing something but what ? Looking on the internet for a hint, I see that python3 has an os.get_terminal_size(). Please, is there something similar for python2 ? Cheers -- Alex -- https://mail.python.org/mailman/listinfo/python-list
Re: get the terminal's size
Hi, Grant Edwards : >>export COLUMNS LINES > That will tell you the terminal size at the time Python was started. Ok, I think tracking these changes in real time is not worth the work to be done using Python2. I think at last I'll rewrite this (little) programe in Python3 in order to use get_terminal_size(). Bye -- Alex -- https://mail.python.org/mailman/listinfo/python-list
Re: get the terminal's size
Hi Thomas >> Looking on the internet for a hint, I see that python3 has an >> os.get_terminal_size(). > Use that then. Up to now I wanted to keep compatibility with a big bunch of code in Python2 that I do no maintain by myself. Well, I saw that get_terminal_size() follows the windows resizings. Whenever I consider forking to Python3, this would be my 1st step. >> Please, is there something similar for python2 ? > I suspect there is some solution in the curses module... I did dir(curse) but I could not see if something goes this way. Bye -- Alex -- https://mail.python.org/mailman/listinfo/python-list
Re: get the terminal's size
On 2019-01-14, Peter Otten <__pete...@web.de> wrote: > Grant Edwards wrote: > > os.environ["COLUMNS"] > >> [...] will tell you the terminal size at the time Python was started. > > I admit that none of my scripts is ambitious enough to try and track > changes in terminal size. > > But still, Grant's post prompted me to reread the doc and source of > shutil.get_terminal_size(), and I think I should warn you that the > environment variables take precedence over ioctl()-based detection > in os.get_terminal_size(). For non-interactive programs, the environment variable approach is usually good enough. For interactive programs you use ncurses, slang, newt, or somesuch library, and they deal with tracking the window size for you (mostly). -- Grant Edwards grant.b.edwardsYow! My haircut is totally at traditional! gmail.com -- https://mail.python.org/mailman/listinfo/python-list
Re: get the terminal's size
Grant Edwards wrote: os.environ["COLUMNS"] > [...] will tell you the terminal size at the time Python was started. I admit that none of my scripts is ambitious enough to try and track changes in terminal size. But still, Grant's post prompted me to reread the doc and source of shutil.get_terminal_size(), and I think I should warn you that the environment variables take precedence over ioctl()-based detection in os.get_terminal_size(). I'll keep the exports for now because even for a pipe $ python3 -c 'import shutil; print(shutil.get_terminal_size())' | cat os.terminal_size(columns=80, lines=24) $ export LINES COLUMNS $ python3 -c 'import shutil; print(shutil.get_terminal_size())' | cat os.terminal_size(columns=137, lines=42) the current terminal is usually my final target. -- https://mail.python.org/mailman/listinfo/python-list
Re: get the terminal's size
On 2019-01-14, Peter Otten <__pete...@web.de> wrote: > >> I want to know the number of columns of the terminal where python2 writes >> it's outputs. >> >> In a terminal, I type >> $ echo $COLUMNS >> 100 >> >> But in Python, os.getenv("COLUMNS") gets nothing. >> It gets nothing as well if I try to read the output of "echo $COLUMNS" >> from a subprocess. [...] > If you see similar output consider adding > > export COLUMNS LINES > > to your .bashrc or equivalent. That will tell you the terminal size at the time Python was started. If the terminal size has changed while Python was running, those environment variables will be wrong. You need to use the TIOCGWINSZ ioctl call: http://www.delorie.com/djgpp/doc/libc/libc_495.html And to detect the size changes (so you know _when_ you need to do the above), you need to attach a signal handler for the WINCH signal. -- Grant Edwards grant.b.edwardsYow! Should I do my BOBBIE at VINTON medley? gmail.com -- https://mail.python.org/mailman/listinfo/python-list
Re: get the terminal's size
On 14/01/2019 12.57, Alex Ternaute wrote: > Hi there, > > I want to know the number of columns of the terminal where python2 writes > it's outputs. > > In a terminal, I type > $ echo $COLUMNS > 100 > > But in Python, os.getenv("COLUMNS") gets nothing. > It gets nothing as well if I try to read the output of "echo $COLUMNS" > from a subprocess. > > I feel that I'm missing something but what ? > > Looking on the internet for a hint, I see that python3 has an > os.get_terminal_size(). Use that then. > Please, is there something similar for python2 ? I suspect there is some solution in the curses module... -- https://mail.python.org/mailman/listinfo/python-list
Re: get the terminal's size
Hi, Peter Otten : >> In a terminal, I type $ echo $COLUMNS 100 >> But in Python, os.getenv("COLUMNS") gets nothing. >> I feel that I'm missing something but what ? > $ export COLUMNS Thank you very much ! -- Aelx -- https://mail.python.org/mailman/listinfo/python-list
Re: get the terminal's size
Alex Ternaute wrote: > Hi there, > > I want to know the number of columns of the terminal where python2 writes > it's outputs. > > In a terminal, I type > $ echo $COLUMNS > 100 > > But in Python, os.getenv("COLUMNS") gets nothing. > It gets nothing as well if I try to read the output of "echo $COLUMNS" > from a subprocess. > > I feel that I'm missing something but what ? $ python -c 'import os; print os.environ["COLUMNS"]' Traceback (most recent call last): File "", line 1, in File "/usr/lib/python2.7/UserDict.py", line 23, in __getitem__ raise KeyError(key) KeyError: 'COLUMNS' $ export COLUMNS $ python -c 'import os; print os.environ["COLUMNS"]' 157 If you see similar output consider adding export COLUMNS LINES to your .bashrc or equivalent. > Looking on the internet for a hint, I see that python3 has an > os.get_terminal_size(). > Please, is there something similar for python2 ? > > Cheers -- https://mail.python.org/mailman/listinfo/python-list
get the terminal's size
Hi there, I want to know the number of columns of the terminal where python2 writes it's outputs. In a terminal, I type $ echo $COLUMNS 100 But in Python, os.getenv("COLUMNS") gets nothing. It gets nothing as well if I try to read the output of "echo $COLUMNS" from a subprocess. I feel that I'm missing something but what ? Looking on the internet for a hint, I see that python3 has an os.get_terminal_size(). Please, is there something similar for python2 ? Cheers -- Alex -- https://mail.python.org/mailman/listinfo/python-list