Is shutil.get_terminal_size useless?
steve+python at pearwood.info
Sat Jan 28 11:15:25 EST 2017
On Sat, 28 Jan 2017 10:50 pm, Chris Angelico wrote:
> On Sat, Jan 28, 2017 at 9:49 PM, Steve D'Aprano
> <steve+python at pearwood.info> wrote:
>> The terminal size doesn't change just because I'm piping output to
>> another process. Using the terminal size as a proxy for "being piped" is
>> sheer insanity.
> In a sense, there _is no_ terminal size when you're being piped to
> another process.
In which sense, and why do you think it is relevant?
There clearly is a terminal, because that's where I'm running the code.
Regardless of whether I pipe it to grep or cat or something else, the
output from *that* process still ends up in the same terminal that I typed
the command in.
I acknowledge that there are cases where there is no terminal. As you say:
> Likewise if you're running in some detached
> (non-terminal) context,
Then get_terminal_size() should raise, unless you explicitly ask for a
> or if you're being run over some remote link
> that hasn't transmitted terminal size info,
I think that the possibility of having such a remote link is a failure of
the remote protocol being used. (ssh? telnet?) But it is what it is.
Perhaps there genuinely are circumstances where the terminal size exists
but is unknowable -- but the example code isn't one of them.
> etc, etc, etc, etc. It's
> not a proxy for "being piped" - it's that when your output isn't going
> to a terminal, asking "what is my terminal size" isn't particularly
Then explain why os.get_terminal_size() returns the correct answer.
The output might not be going to a terminal (not directly at least) but the
question isn't "what's the size of the terminal that output is going to".
The question is "what's the size of the terminal that this process is
running in", and that has an answer regardless of where output is piped.
> Would you expect that a process started from systemd is told about the
> size of the terminal in which you ran "systemctl start servicename"? I
> doubt it.
I wouldn't make any assumptions at all about what systemd does. For all I
know, it hard codes a size of (300, 100) into every single process because
that's the size of terminals on Lennart's laptop.
> Would you expect a cronjob to use the terminal size when you
> most recently edited crontab? No.
Of course not -- the terminal where you edited crontab is not where the
process is running. Why would it be the least bit relevant?
> So why should a program that's being
> piped into something else automatically assume the size of the other
> program's terminal?
Because the other program is running in the same terminal as the first
grep foo * | wc -l
Both grep and wc are running in the same terminal. (Assuming there is any
terminal at all.)
> You might well be a completely background process.
And if that background process is running in a terminal? What's your point?
I'm not disputing that there are processes where no terminal exists at all.
That's a red herring. os.get_terminal_size() returns the correct result.
Why doesn't shutil?
> You can still ask the concrete question about terminal size,
You mean like a function called get_terminal_size()?
> and that's in the 'os' module. The 'shutil' module also looks at
> environment variables,
Why? We already have ways to look at environment variables.
The only complication here is that, perhaps, there may be more than one set
of environment variables to compare, and some order that they should be
preferred. It is often the Unix way that there might be two, or twenty-two
*wink* different environment variables to communicate this information. But
in this case, I'm not able to find anything other than the two standard
variables, COLUMNS and LINES.
Aside: technically these are shell variables, and they may not exist in
arbitrary shells. They also need to be explicitly exported as environment
variables to become visible to Python. See this StackOverflow question for
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.
More information about the Python-list