Discussion:
Philosophical question
(too old to reply)
Michael F. Stemper
2017-06-14 19:15:48 UTC
Permalink
Why doesn't bash export $COLUMNS?

I wanted to add some code within a program to have its output
nicely formatted, no matter the width of the terminal in which
it was being run. Unfortunately, I wasn't able to do so, because
it didn't have access to $COLUMNS.

The following simple example shows that $COLUMNS is not exported:

***@hostname$ echo $COLUMNS
80
***@hostname$ cat > col
#!/bin/bash
echo $COLUMNS
***@hostname$ chmod +x col
***@hostname$ ./col

***@hostname$ export COLUMNS
***@hostname$ ./col
80
***@hostname$

Now that I've moved beyond denial, I'd like to understand *why*
this is so. Does anybody have a good reason why programs and
scripts shouldn't have automatic access to this particular
variable?
--
Michael F. Stemper
Life's too important to take seriously.
Joe Rosevear
2017-11-26 10:03:18 UTC
Permalink
Post by Michael F. Stemper
Why doesn't bash export $COLUMNS?
That is a good question. I will try to answer it.

This Google search:

why is columns variable not available in my script

turned up this helpful webpage:

https://stackoverflow.com/questions/1780483/lines-and-columns-environmental-variables-lost-in-a-script

In short the webpage says

The variables $LINES and $COLUMNS are shell variables, not
environmental variables, and thus are not exported to the child
process...

Maybe this means that the code which creates the shell also defines the
variables COLUMNS and LINES. As for why they are not exported by
default, I think that is left undone for the benefit of those who might
not want the variable exported.

Think about it. The shell you use at the command line has a window or
a text console that corresponds to it. The shell used in a script is
not the same shell. (Examine $SHLVL from inside a running script and
from the command line to see this.) The shell used in a script is like
a phantom--it has no window or console of its own. Having no window or
console, it is right that COLUMNS is un-defined in it.

So here are two work-arounds:


1. The above webpage says that you can get the value of COLUMNS inside
a script this way:

columns=$(tput cols)


2. Use the "source" command, or ".", its equivalent. This allows you
to run a script in the current shell. Example:

. tryit

Because it runs in the current shell, it will see the value of COLUMNS
even if it has not been exported.


-Joe
Michael F. Stemper
2018-08-11 19:28:58 UTC
Permalink
Post by Joe Rosevear
Post by Michael F. Stemper
Why doesn't bash export $COLUMNS?
That is a good question. I will try to answer it.
[snip]
Post by Joe Rosevear
Maybe this means that the code which creates the shell also defines the
variables COLUMNS and LINES. As for why they are not exported by
default, I think that is left undone for the benefit of those who might
not want the variable exported.
I fail to see how this helps anybody. If somebody doesn't need COLUMNS
or LINES, the exporting of those variables wouldn't force them to use
them. If somebody wants to have a variable COLUMNS that means something
other than the width of the xterm in which it's running, all that they
have to do is clobber it.
Post by Joe Rosevear
Think about it. The shell you use at the command line has a window or
a text console that corresponds to it. The shell used in a script is
not the same shell.
No, of course not. However, when it's run interactively, it's run from
an xterm which has a width. Knowledge of this width is useful for nicely
formatting output.

For instance, ls formats its output based upon the width of the window
in which it's being run -- even if it's invoked from a script. To see
this, use the following:

***@hostname$ cat llll
#!/bin/bash
ls
***@hostname$ ll llll
-rwxrwxr-x 1 username username 15 Aug 11 14:22 llll
***@hostname$

Run it in a directory with lots of files, then widen the window
significantly and run it again.

So ls can access the width of the xterm in which it's being run. Other
programs (such as vi) seem to be able to do so as well.
Post by Joe Rosevear
The shell used in a script is like
a phantom--it has no window or console of its own. Having no window or
console, it is right that COLUMNS is un-defined in it.
I guess that we'll just have to disagree about what's right.
Post by Joe Rosevear
1. The above webpage says that you can get the value of COLUMNS inside
columns=$(tput cols)
That is slick! Thanks.
Post by Joe Rosevear
2. Use the "source" command, or ".", its equivalent. This allows you
. tryit
I'm aware of this syntax, although I hadn't thought of it with respect
to this. However, I'm firmly of the belief that one should be able to
execute anything, whether it be a program or a script, the same way.

Thanks for responding, though, and sorry about the necro-post.
--
Michael F. Stemper
Soglin for governor.
Loading...