5 Best Ways to Get Linux Console Window Width in Python

πŸ’‘ Problem Formulation: When developing console applications in Python for Linux systems, developers may need to tailor outputs based on the size of the console window (terminal). For instance, a program might require the console window width to format text appropriately. The input in this context is the current state of the terminal, while the desired output is an integer value representing the terminal’s width in characters.

Method 1: Using the fcntl, termios, and struct Modules

This method utilizes low-level system calls in Python to obtain terminal dimensions and is typically reliable and direct. It involves the fcntl.ioctl function, along with the TIOCGWINSZ operation from the termios module to retrieve the window size structure, which is then unpacked using the struct module to yield the width.

Here’s an example:

import fcntl
import termios
import struct

def get_terminal_width():
    h, w, hp, wp = struct.unpack('HHHH',
        fcntl.ioctl(0, termios.TIOCGWINSZ,
        struct.pack('HHHH', 0, 0, 0, 0)))
    return w

print("Terminal width:", get_terminal_width())

Output:

Terminal width: 80

This code defines a function get_terminal_width that retrieves and unpacks the window size structure to get the width of the terminal. The integers in the unpacked tuple represent the height and width of the window, as well as the height and width in pixels, though we only extract the width here for our purposes.

Method 2: Using the os.get_terminal_size Function

Python’s os module offers a straightforward function called get_terminal_size which returns an os.terminal_size object from where the window’s width can be accessed. It’s part of Python’s standard library, making it a quick and high-level method for obtaining console dimensions.

Here’s an example:

import os

def get_terminal_width():
    size = os.get_terminal_size()
    return size.columns

print("Terminal width:", get_terminal_width())

Output:

Terminal width: 80

In this snippet, the get_terminal_size function is called without arguments, automatically using the file descriptor for stdout. The resulting os.terminal_size object has a columns attribute that stores the width of the terminal, which is returned by the get_terminal_width function.

Method 3: Using the subprocess Module to Call stty size

Linux provides a standard command stty that can be used to alter and print terminal line settings. In this method, Python’s subprocess module is used to invoke stty size, which prints out the height and width of the terminal. The output is captured and parsed to get the width value.

Here’s an example:

import subprocess

def get_terminal_width():
    output = subprocess.check_output(['stty', 'size']).decode('utf-8')
    return int(output.split()[1])  # The width is the second item

print("Terminal width:", get_terminal_width())

Output:

Terminal width: 80

Here the subprocess.check_output function runs the stty size command. The output is a string with the height and width, which is then decoded from bytes to a string, split, and the second item (the width) is converted to an integer and returned by the get_terminal_width function.

Method 4: Using the curses Module

The curses module provides a way to work with windowed text modes and can be used to get the terminal size as well. When the curses screen is initialized, the window dimensions can be queried. This method works within the context of a curses application and may not be suitable for simple scripts.

Here’s an example:

import curses

def get_terminal_width(stdscr):
    height, width = stdscr.getmaxyx()
    return width

wrapper_func = curses.wrapper(get_terminal_width)
print("Terminal width:", wrapper_func)

Output:

Terminal width: 80

After initializing the curses screen with curses.wrapper(), the width and height can be obtained with the getmaxyx method. Note that curses.wrapper takes a function that should accept a screen object as an argument, and this function should return the width.

Bonus One-Liner Method 5: Using a Shell Command with Python

You can also use a one-liner in Python to get the width by executing a shell command that prints the console width. This makes use of the os.popen() function, which opens a pipe to or from the command line.

Here’s an example:

import os

terminal_width = os.popen('tput cols').read().strip()
print("Terminal width:", terminal_width)

Output:

Terminal width: 80

The shell command tput cols is executed which outputs the terminal width. The result is then read from the pipe, stripped of any trailing newline, and stored in the variable terminal_width.

Summary/Discussion

  • Method 1: fcntl, termios, struct. Precise and direct, can be complex for beginners. Low-level approach.
  • Method 2: os.get_terminal_size. Simple and quick, but Python 3.3+ only. High-level, may not work on terminals not supporting ioctls.
  • Method 3: subprocess ‘stty size’. Leverages built-in Linux tools, introduces dependent on external command, extra overhead for spawning subprocess.
  • Method 4: curses module. Ideal for curses applications, less practical for non-curses scripts. Requires understanding of the curses library.
  • Bonus Method 5: Shell command with os.popen. One-liner trick, easy but depends on the shell utility tput being available.