bashmacosmacos-big-surtput

What changes the result of the 'tput lines' command?


I executed following code on bash on the terminal which have LINES=50. The result of 'tput lines' command varied. I have no idea to explain this results. Why the 'tput lines' command may returns '24' ?

The code:

#!/bin/sh
echo $LINES
tput lines
tput lines 2>/dev/null
echo $(tput lines)
echo $(tput lines 2>/dev/null)
true && tput lines
true && tput lines 2>/dev/null
true && echo $(tput lines)
true && echo $(tput lines 2>/dev/null)
echo $TERM
echo $TERM 2>/dev/null
echo $(echo $TERM)
echo $(echo $TERM 2>/dev/null)
true && echo $TERM
true && echo $TERM 2>/dev/null
true && echo $(echo $TERM)
true && echo $(echo $TERM 2>/dev/null)

The result 1:

$ ./testtput

50
50
50
24
50
50
50
24
xterm-256color
xterm-256color
xterm-256color
xterm-256color
xterm-256color
xterm-256color
xterm-256color
xterm-256color

The result 2:

$ ./testtput | pbcopy

50
24
50
24
50
24
50
24
xterm-256color
xterm-256color
xterm-256color
xterm-256color
xterm-256color
xterm-256color
xterm-256color
xterm-256color

My environment:


Solution

  • When standard output is connected to a terminal, tput will query the terminal device to find get the window dimensions.

    When you put tput into a command substitution, $(tput lines), its standard output is connected to a pipe, not the terminal. In this case it will use the LINES environment variable, or the default size from the terminfo entry for the terminal type.

    Since you have LINES=50 but aren't getting that when you use the pipe, I suspect you forgot to export the variable. Use

    export LINES=50
    

    and then try again.

    UPDATE:

    I misread the example (it's hard to tell which commands go with each output). Now I think that when standard output isn't a terminal, it tries standard error. It only falls back to the default when neither of them is a terminal. So you get 24 when standard output is the pipe for command substitution, and standard error is redirected to /dev/null.