Is shutil.get_terminal_size useless?

Michael Torrie torriem at
Sat Jan 28 11:03:22 EST 2017

On 01/28/2017 04:00 AM, Steve D'Aprano wrote:
>> $ COLUMNS=123 python3 | cat
>> shutil: os.terminal_size(columns=123, lines=999)
>> os: os.terminal_size(columns=72, lines=48)

Interesting. On my machine with Python 3.4, calling
os.get_terminal_size() and piping the output results in the exception
OSError: [Errno 25] Inappropriate ioctl for device

Which is what I'd expect, seeing as there's no tty and no terminal
emulator. I'm not sure why you're not seeing that error also.

> Unless your terminal *actually is* 123 columns wide, I don't see that as an
> advantage. I see that as "Hey look, we can fool shutil into returning
> absolute garbage instead of the terminal size!"

Influencing the column width used by a program for output is very useful
and is often used in shell scripting and piping data.  This allows
programs to just have to use one mechanism to determine line length,
regardless of whether it's running on a tty or connected to a pipe.

> I can already read environment variables using os.getenv() and os.environ,
> so this gives me no new functionality.

Sure but working through shutils provides a uniform way of getting the
maximum column width.  Furthermore using shutils is probably more portable.

I'm not sure if you can override LINES or not, but even if you can't
that's pointless.

> But what happens if you resize the terminal while the process is running?
> Again, the os.get_terminal_size() correctly returns the updated size, while
> shutil.get_terminal_size() doesn't.

For a program that's communicating with a tty, you just have to call
shutil.get_terminal_size() again to get the updated size.

For your piped process, the question doesn't make sense.  You can't
resize a pipe.  The only process that can respond to terminal changes is
the final process in your chain that's actually writing to the tty.

If your process is talking to a pipe, then the only thing you can do is
make an arbitrary decision about the line length (columns==999 means
unlimited, otherwise limit to columns).  Nothing else makes sense.

More information about the Python-list mailing list