Created
November 28, 2011 10:00
-
-
Save bcbnz/1399831 to your computer and use it in GitHub Desktop.
Try to find the size of a terminal window.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import fcntl | |
import os | |
import struct | |
import sys | |
import termios | |
def window_size(fd): | |
"""Try to get the size of a terminal window. | |
:param fd: The file descriptor of the terminal window. | |
:return: The size of the terminal window as a tuple (width, height), or None | |
if it cannot be determined. | |
""" | |
try: | |
# Make an IOCTL call to get the size. The second argument is a constant | |
# telling IOCTL we want the size. The third argument is a string | |
# of the same length as the output data, in this case four bytes (two | |
# each for width and height). | |
s = fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234') | |
# Unpack the resulting structure into two values. | |
size = struct.unpack('hh', s) | |
except: | |
return None | |
# Flip the result into the desired order and ensure the values are integers. | |
return (int(size[1]), int(size[0])) | |
def terminal_size(): | |
"""Try to get the size of the current terminal. The following series of | |
steps is used to get the size: | |
* Try to get the size from one of the sys.stdout, sys.stderr or sys.stdin | |
file descriptors. | |
* If that fails, open the controlling terminal of the process (defined in | |
os.ctermid) and try to get the size from that. | |
* If that fails, try reading it from the LINES and COLUMNS environment | |
variables. | |
* Finally, default to an 80x24 terminal. | |
:return: The size of the current terminal window as a tuple (width, height). | |
""" | |
# Try getting it from one of the standard file descriptors. | |
print 'Trying IOCTL on stdout...' | |
size = window_size(sys.stdout.fileno()) | |
if not size: | |
print 'Trying IOCTL on stderr...' | |
size = window_size(sys.stderr.fileno()) | |
if not size: | |
print 'Trying IOCTL on stdin...' | |
size = window_size(sys.stdin.fileno()) | |
# If that didn't work, open the controlling terminal and try getting the | |
# size from there. | |
if not size: | |
print 'Trying IOCTL on controlling terminal...' | |
try: | |
fd = os.open(os.ctermid(), os.O_RDONLY) | |
size = window_size(fd) | |
os.close(fd) | |
except: | |
pass | |
# If that didn't work, try the environment variables. | |
if not size: | |
print 'Trying COLUMNS/LINES shell variables...' | |
try: | |
size = (os.environ['COLUMNS'], os.environ['LINES']) | |
except: | |
pass | |
# Unable to find the real size, assume 80x24. | |
if not size: | |
print 'Assuming 80x24...' | |
size = (80, 24) | |
# Done. | |
return size | |
print terminal_size() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment