Explain Codes LogoExplain Codes Logo

How to get Linux console window width in Python

python
text-based-interfaces
terminal-size
console-width
Nikita BarsukovbyNikita Barsukov·Nov 20, 2024
TLDR

To swiftly fetch the console width in a Python script, employ the shutil.get_terminal_size() function from the shutil module or use the os.get_terminal_size() function from the built-in os library. Both methods return a tuple where the width (columns) of the console is the first element as shown below:

import shutil width, _ = shutil.get_terminal_size() print("Width:", width)

The above code snippet conveniently prints the width of your console.

Role in Text-based Interfaces

The console width is instrumental in devising text-based interfaces. The benefits multiply with the prevention of line wrapping achieved with the columns attribute obtained from shutil.get_terminal_size().

Piping and Redirection: A Special Case

When you've got piping or output redirection in play, it's safe to bet on os.get_terminal_size(0). By doing so, the real terminal dimensions are fetched even if your output is not interacting directly with it.

import os width, _ = os.get_terminal_size(0) print("Width:", width) # because width matters more than talent! (Just kidding!)

Digging Deeper: Fallbacks and Lower-Level APIs

Fallback Strategy

To effectively handle situations where terminal size retrieval might fail, adopt the fallback technique. Provide a default size to the get_terminal_size(fallback=(80, 20)) function for a seamless operation, even in the face of adversity.

width, _ = shutil.get_terminal_size(fallback=(80, 20)) # 80 because why not!

Low-level ioctl System Call

If you dare to delve into the deeper Linux-specific realms, you could use the fcntl.ioctl system calls. Invoke these calls with TIOCGWINSZ to get into the low-level mechanisms for extracting the window size:

import fcntl import termios import struct fd = open(0) # stdin because we're all standard here! buf = fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234') # 1234 because it's easy to remember! width, _ = struct.unpack('hh', buf) # 'hh' because we're happy here!

Platform and Version Compatibility

These methods are cross-platform and run on Linux, Mac OS, and Windows. For Pythonistas using versions under 3.3, get_terminal_size() has got your back with a backport.

A Ride into Alternatives

Linux-specific 'stty size' Command

For those who are partial to Linux, calling stty size would do the trick:

import os dimensions = os.popen('stty size', 'r').read().split() # split because we're all split-brained! width = int(dimensions[1]) # who cares about rows when we've got mighty columns!

For this one, remember to proceed with caution, as this might not deliver in a non-interactive shell.

When not to use os.environ["COLUMNS"]

You may come across scripts that use os.environ["COLUMNS"]; however, this variable can be misleading as it may not represent the current console width, particularly if the console is resized post environment variables initialization.

Comprehensive Tips, Tricks, and Use Cases

Handling Practical Scenarios

Being aware of your terminal's width is key to formatting output, creating dynamic tables, and designing CLI tools. Here's how you use the width in a practical case:

# Making a header that fits any console's width - No discrimination here! header = "My CLI Tool".center(width, '-') print(header) # Creating tables that fit any terminal width - We're all about fitting in! column_width = width // 3 print(f"{ 'Name'.ljust(column_width) }{ 'Status'.ljust(column_width) }{ 'Output'.ljust(column_width) }")

Width Versus Pixel Dimensions

Ensure that you're clear about what you're dealing with. The terminal width pertains to the number of characters per line, not pixel dimensions. This understanding is critical for text-oriented applications.

More Than a Width

Digging deeper into terminal interactions would lead you to the curses library in Python. This module helps create text-based user interfaces in a more sophisticated manner.