Unable to see os.environ['COLUMNS']

Grant Edwards grante at visi.com
Mon Sep 15 07:02:35 CEST 2008


On 2008-09-13, Tim Chase <python.list at tim.thechases.com> wrote:
> Not sure what's going on here and hoping for some insight:
>
>    tim at rubbish:~$ echo $COLUMNS
>    129
>    tim at rubbish:~$ python2.5
>    Python 2.5.2 (r252:60911, May 28 2008, 08:35:32)
>    [GCC 4.2.4 (Debian 4.2.4-1)] on linux2
>    Type "help", "copyright", "credits" or "license" for more 
> information.
>    >>> import os
>    >>> os.environ.get('COLUMNS')
>    >>>  'COLUMNS' in os.environ
>    False
>
> I can coerce it by using
>
>    tim at rubbish:~$ COLUMNS=$COLUMNS python2.5
>    Python 2.5.2 (r252:60911, May 28 2008, 08:35:32)
>     [GCC 4.2.4 (Debian 4.2.4-1)] on linux2
>    Type "help", "copyright", "credits" or "license" for more 
> information.
>    >>> import os
>    >>> 'COLUMNS' in os.environ
>    True
>
> However, this seems hokey to me.
>
> FWIW, this is in Bash on Debian.

In bash (and other descendants of the Bourne shell), there are
two types of environment variables: 1) local variables that are
not passed on to child processes and 2) exported variables that
_are_ passed on to children.

By default, when a variable is created it is local and will not
be inherited by sub-processes.

> What's the best way to read what seems to be a
> pseudo-environment variable?

You can't.  You need to export the variable in the parent shell
before it exec's the child:

$ echo $COLUMNS
80

$ python -c "import os; print os.environ['COLUMNS']"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/lib/python2.5/UserDict.py", line 22, in __getitem__
    raise KeyError(key)
KeyError: 'COLUMNS'

$ export COLUMNS

$ python -c "import os; print os.environ['COLUMNS']"
80


Now, on to the question you're about to ask:

Q: How do I find out how big my terminal is from a Python
   program?

A: You use the TIOCGWINSZ ioctl call on the terminal's file
   descriptor:

>>> import sys,fcntl,termios,struct
>>> data = fcntl.ioctl(sys.stdout.fileno(), termios.TIOCGWINSZ, '1234')
>>> struct.unpack('hh',data)
(24, 80)

There's a more detailed explanation here (including an
explanation of what the third parameter to ioctl() does, and
how you detect changes in the window size):

  http://mail.python.org/pipermail/python-list/2006-February/365710.html

There's also chance that you'd be better off just using ncurses or
newt for screen management, but that's another post.

-- 
Grant







More information about the Python-list mailing list