This was on a Solaris 10 machine.
The puzzle
I was working in a terminal window (xterm to be precise) where I had been doing some work throughout the day and I finally got to the point to set an environment variable and check its value (my login shell is csh).foo:/home/andreas 151 % setenv THIS something foo:/home/andreas 152 % echo T=$THIS T=Oh, I just set the variable and then it reports to be empty? How strange.
I checked the environment:
foo:/home/andreas 153 % env | grep THIS THIS=somethingSo this looks ok, the var is definitly set but why does echo report it as empty? (and printf showed the same).
I tested other variable names but they behaved normal: echo showed their values.
I opened a new terminal window and tested this particular variable and others: all worked normal.
How can that be? What was so special about this session?
I trussed echo (for the non-Solaris users: truss is the Solaris command to inspect the behaviour of processes showing system calls etc.) and I saw that it is called without an argument, its env list shows THIS to be set though:
foo:/home/andreas 157 % truss -aeilf -r all -v all echo $THIS 26445/1: execve("/usr/bin/echo", 0xFFBFE954, 0xFFBFE95C) argc = 1 26445/1: argv: echo 26445/1: envp: USER=andreash LOGNAME=andreash HOME=/home/andreash 26445/1: ... 26445/1: THIS=something ...Think about this for a while before you proceed to the next section for the solution.
The solution
I finally got to the point where I started to check other things which are set in csh: aliases and variables (not env).The list of aliases did not show anything particular.
And then I ran set:
foo:/home/andreas 161 % set CSHRC /home/andreas/.cshrc HOSTNAME foo ... THIS ...So here you go: in some of my previous work that day in that particular terminal I must have set the variable THIS to empty and forgotten about it and despite setting the environment variable the first setting was still taken into account.
This is one of the traps of csh (others might call it feature, and of course this was new to me).
The Bourne shell family uses export to distinguish and this trap does not exist.
Summary
Here it is again in summary to remember:in csh when you 'set' a variable a subsequent 'setenv' will not replace the variable in the current context.
set A=aaaaaa setenv A bbbbbb echo A=$A A=aaaaaa unset A echo A=$A A=bbbbbbGoing a little further: if you reverse this and first set a variable via setenv and then via set the second value will prevail
setenv A bbbbbb set A aaaaaa echo A=$A A=aaaaaai.e. variables set with set always take precedence over variables set with setenv. Very important to remember. And only the latter will be exported to new shells though. I guess it would be a wise rule to keep a distinct set of names for set/setenv, otherwise things can get confusing (as in my starting puzzle) or things can even go wrong (when programming with false assumptions).
This was great to reead
ReplyDelete