Python os.get_terminal_size Function
Last modified April 11, 2025
This comprehensive guide explores Python's os.get_terminal_size
function, which retrieves terminal dimensions. We'll cover usage patterns,
fallback values, and practical terminal formatting examples.
Basic Definitions
The os.get_terminal_size
function returns terminal dimensions
as columns (width) and lines (height). It's available in Python 3.3+.
Returns a named tuple os.terminal_size with columns and lines attributes. If terminal size can't be determined, returns fallback or (80, 24) default.
Basic Terminal Size Check
The simplest use retrieves current terminal dimensions. This example shows both attribute and index access to the size values.
import os # Get terminal size size = os.get_terminal_size() # Access via attributes print(f"Terminal width: {size.columns} columns") print(f"Terminal height: {size.lines} lines") # Access via index print(f"Dimensions: {size[0]}x{size[1]}")
This demonstrates two ways to access the dimensions. The named tuple provides clear attribute names (columns, lines) and maintains index compatibility.
The output will vary based on your actual terminal window size when running.
Providing Fallback Values
When terminal size can't be determined (like in non-terminal environments), you can specify fallback dimensions. This prevents default (80, 24) values.
import os # Custom fallback dimensions fallback_size = os.terminal_size((120, 30)) # Get size with fallback size = os.get_terminal_size(fallback_size) print(f"Using dimensions: {size.columns}x{size.lines}") # Alternative tuple fallback size = os.get_terminal_size((100, 20)) print(f"Alternative fallback: {size.columns}x{size.lines}")
The first approach uses os.terminal_size for the fallback. The second uses a simple tuple, which gets converted automatically.
Fallbacks are useful when running in IDEs or redirected output where terminal size detection fails.
Dynamic Text Wrapping
Using terminal width, we can implement dynamic text wrapping that adapts to the current terminal size. This creates better formatted output.
import os import textwrap def print_wrapped(text): width = os.get_terminal_size().columns - 4 # Account for margins wrapper = textwrap.TextWrapper(width=width) print("\n".join(wrapper.wrap(text))) long_text = ("This is a long paragraph that needs to be wrapped " "according to the current terminal width. The text will " "automatically adjust to fit within the available space.") print_wrapped(long_text)
This calculates available width by subtracting margins from terminal width. The textwrap module then handles the line breaking at word boundaries.
Resizing the terminal and rerunning will produce different wrapping behavior.
Progress Bar Width Adjustment
Terminal width is crucial for progress bars. This example shows a dynamic progress bar that fills available width.
import os import time def show_progress(iteration, total): width = os.get_terminal_size().columns - 10 progress = int(width * iteration / total) bar = "[" + "#" * progress + " " * (width - progress) + "]" print(f"\r{bar} {iteration}/{total}", end="", flush=True) # Simulate progress for i in range(1, 101): show_progress(i, 100) time.sleep(0.05) print() # Newline after completion
The progress bar uses nearly full terminal width, reserving space for the counter. It updates in-place using carriage return.
The bar width automatically adjusts when terminal is resized during execution.
Table Column Sizing
Terminal width helps create properly sized tables. This example distributes columns proportionally based on content and available width.
import os data = [ ["ID", "Name", "Description", "Value"], [1, "Item A", "First sample item", 42.5], [2, "Item B", "Second item with longer description", 127.3], [3, "Item C", "Short", 8.99] ] def print_table(rows): term_width = os.get_terminal_size().columns col_widths = [ max(len(str(row[i])) for row in rows) for i in range(len(rows[0])) ] # Adjust for terminal width total_needed = sum(col_widths) + 3 * (len(col_widths) - 1) if total_needed > term_width: scale = term_width / total_needed col_widths = [int(w * scale) for w in col_widths] # Print rows for row in rows: print(" ".join(str(cell).ljust(width) for cell, width in zip(row, col_widths)) print_table(data)
This calculates initial column widths based on content, then scales down if needed to fit terminal width. Each cell is left-justified in its column.
The table maintains readability while adapting to different terminal sizes.
Vertical Space Management
Terminal height helps manage vertical output. This example paginates long content based on available lines.
import os def paginate_content(lines): height = os.get_terminal_size().lines - 3 # Reserve space for prompts current = 0 while current < len(lines): print("\n".join(lines[current:current+height])) current += height if current < len(lines): input("-- Press Enter for more --") # Generate sample content content = [f"Line {i}: Sample content..." for i in range(1, 101)] paginate_content(content)
This displays content one page at a time, pausing when the screen fills. The height reserve accounts for command prompts and pagination controls.
Users can view long output comfortably without scrolling past content.
Responsive UI Layout
For terminal applications, responsive layouts adapt to terminal dimensions. This example shows a multi-panel layout that adjusts to size changes.
import os def draw_layout(): size = os.get_terminal_size() width, height = size.columns, size.lines # Header print("=" * width) print("RESPONSIVE TERMINAL UI".center(width)) print("=" * width) # Calculate panel sizes left_width = width // 3 right_width = width - left_width - 1 # Account for separator # Content rows (reserve 4 lines for header/footer) for i in range(2, height - 2): if i == 3: left = "MAIN MENU".ljust(left_width) right = f"Terminal: {width}x{height}".ljust(right_width) elif i == height // 2: left = "SELECTION".ljust(left_width) right = "CONTENT AREA".center(right_width) else: left = "".ljust(left_width) right = "".ljust(right_width) print(left + "|" + right) # Footer print("=" * width) print(f"q: quit | r: refresh".ljust(width)) while True: draw_layout() cmd = input("Command: ") if cmd.lower() == 'q': break
This creates a two-panel layout that recalculates dimensions on each draw. The header, footer, and content areas adjust to current terminal size.
Pressing 'r' redraws the layout, showing changes after terminal resizing.
Common Use Cases
- Text formatting: Wrapping text to terminal width
- UI elements: Creating responsive terminal interfaces
- Progress indicators: Dynamic progress bars
- Data display: Tables and grid layouts
- Pagination: Managing long content output
Best Practices
- Provide fallbacks: Handle non-terminal environments
- Account for margins: Reserve space for UI elements
- Cache sizes: For performance in tight loops
- Handle resizing: Consider SIGWINCH signals
- Test edge cases: Very small/large terminals
Source References
Author
List all Python tutorials.