[comp.unix.questions] TERM env.var. in Unix: Why can't I modify it ?

nomann@rimfaxe.diku.dk (Ole Nomann Thomsen) (07/03/90)

Recently I posted this question in comp.unix.questions, but got only one
answer. (This was to "look in /etc/TIMEZONE", which was useful, although 
not sufficient. Thanks to the answerer, sorry I mislaid you name).

Now, I have collected some more data on the problem, which enables me to
describe it more thoroughly (I hope :-).

The system is unix rel. 3.2 vers. 2.1 machine: i386, and I use a csh.

The problem is this:

When I log in from a network-terminal, I get an env. variable, TERM,
that is set to unknown. I cannot change this value to something sensible
since "setenv" doesn't overwrite the existing TERM, but rather creates a
new one, so that I now have two "TERM" env.var.s (and all the applications
can only see the wrong one, surprise surprise).

The problem stems from the program /bin/netlogin. I know this, because I
patched this binary to set an env.var. call "LERM" instead of "TERM". This
results in that I have an immortal env.var.: LERM=unknown, which I can live
with, although it still bothers me (not a pain but an itch).

My questions are:

1. Why (and how) does /bin/netlogin set an immortal env.var., and is it
   harmful to remove it like I did. ?

2. Why can't csh overwrite the TERM=unknown env., (with setenv) when Bourne-
   shell can (with export) ?

To clarify, I include an example run. This is made with the modified
/bin/netlogin, so the problem env.var. is now "LERM".

# This is my unmodified env. notice the unknown "LERM"
#
4% env
HOME=/usr/nomann
PATH=:/bin:/usr/bin:/usr/local/bin:/usr/nomann/bin
LOGNAME=nomann
LERM=unknown
HZ=100
TZ=MET-1MED-2;85/2:00:00,274/2:00:00
DNPRINT=lp -dprinter3
TERM=adm12
#
# I now set LERM to "foo". Notice its absence in the env.
#
5% setenv LERM foo
6% env
HOME=/usr/nomann
PATH=:/bin:/usr/bin:/usr/local/bin:/usr/nomann/bin
LOGNAME=nomann
LERM=unknown
HZ=100
TZ=MET-1MED-2;85/2:00:00,274/2:00:00
DNPRINT=lp -dprinter3
TERM=adm12
#
# "g" is a program that prints the environment, using:
# main(argc, argv, envp) char **envp, **argv;
# and so on.
# notice the two "LERM"s, where the first one is "foo".
#
7% g
HOME=/usr/nomann
PATH=:/bin:/usr/bin:/usr/local/bin:/usr/nomann/bin
LOGNAME=nomann
LERM=foo
HZ=100
TZ=MET-1MED-2;85/2:00:00,274/2:00:00
LERM=unknown
DNPRINT=lp -dprinter3
TERM=adm12
adm12
======================================================================

Now, the most useful behavior of setenv would be to overwrite the 
second instance of "LERM", so that env would see that one. Can anybody
tell me how I can get it to do that ?

PS: Sorry if "LERM" is a rude word in some language (it does sound so :-)/2.



- Ole. (nomann@diku.dk).

"Information is not knowledge" - Frank Zappa. 

leo@ehviea.ine.philips.nl (Leo de Wit) (07/05/90)

In article <1990Jul3.094811.4684@diku.dk> nomann@rimfaxe.diku.dk (Ole Nomann Thomsen) writes:
|Recently I posted this question in comp.unix.questions, but got only one
|answer. (This was to "look in /etc/TIMEZONE", which was useful, although 
|not sufficient. Thanks to the answerer, sorry I mislaid you name).
|
|Now, I have collected some more data on the problem, which enables me to
|describe it more thoroughly (I hope :-).
|
|The system is unix rel. 3.2 vers. 2.1 machine: i386, and I use a csh.
|
|The problem is this:
|
|When I log in from a network-terminal, I get an env. variable, TERM,
|that is set to unknown. I cannot change this value to something sensible
|since "setenv" doesn't overwrite the existing TERM, but rather creates a
|new one, so that I now have two "TERM" env.var.s (and all the applications
|can only see the wrong one, surprise surprise).

I think I know the reason of your problem, and I've got a solution too.
I created a program that adds an extra TERM variable to the environment
(through execve()). It has the same peculiarities you mention, that is:
env only shows the last one, but printenv (BSD) prints both. The AT&T
universe on this Pyramid uses the last one, the UCB universe the first.

|
|The problem stems from the program /bin/netlogin. I know this, because I
|patched this binary to set an env.var. call "LERM" instead of "TERM". This
|results in that I have an immortal env.var.: LERM=unknown, which I can live
|with, although it still bothers me (not a pain but an itch).
|
|My questions are:
|
|1. Why (and how) does /bin/netlogin set an immortal env.var., and is it
|   harmful to remove it like I did. ?

/bin/netlogin just added an extra TERM variable to your environment,
without removing the original one. Subsequent setenvs will set the
first entry, not the second; env will use the last entry found, and
getenv() behaves differently in System V and BSD (the former using the
last, the latter using the first entry if I may believe some simple
tests).

An easy fix without resorting to binary patching is to just unsetenv
TERM, then setenv TERM. This will first reduce the number of TERM
variable entries to one, and then set that one entry.

|
|2. Why can't csh overwrite the TERM=unknown env., (with setenv) when Bourne-
|   shell can (with export) ?
|

Csh does nothing special to the environment, while a Bourne shell first
cleans up its environment (printing out its environment shows it is
sorted and uniqued).  The reason for this probably lays in the fact
that shell variables and environment variables are treated differently
in both shells (there is no such thing as export in the csh, which puts
a shell variable in the environment).

    Leo.