- PATH: series of file system directory prefixes, typically separated by :, which the operating system will apply when asked to execute a file with an incomplete pathname.
- HOME: name of the user's login directory.
- LANG: string used to specify internationalization info.
- $::env(PATH)
- global env ; puts $env(PATH) can alternatively used to identify that the variable is globally available; however, you have to remember to use the global command in EVERY proc that you need to use env. Using the $::env notation is shorter.
The variables that appear in $::env are only those variables which the parental shell places into the environment. Under bash/ksh/sh this is done by a line such as:
MYVAR="this is a test" ; export MYVARwhile in csh/tcsh, you do it like this:
setenv MYVAR "this is a test"Shell variables set but not put into the environment are not accessible by child processes.Also note that while a Tcl program can set new variables or values in $::env , those values will NOT be reflected in the program's parent process.This separation of process data is an intentional part of the various operating systems available today. To communicate new variables or variable values back into the parent, one needs some sort of out of band communication of information; perhaps writing a shell script or file of data which the parent shell then reads.
DKF - Additional notesThe env array is precisely the environment variables of the current process. If you want to pass a variable to a child process, setting it in env is the way to do it. And on Windows, you can't set an environment variable to an empty string, as the OS defines that to be the same as removing the variable completely. (Stupid, but that's the way things are, and working around it - which is possible BTW - is not a good idea as it can cause trouble for some programs to receive empty env-vars when they don't expect it. Keeping the tight binding is thought to be a better idea.)LV During this thread [1] you will see that attempting to set env variables to null is going to result in behavior that your code may not expect. So it is better to not even try to do this on Windows, rather than attempt to write around the quirks.There is only one env array per process. All interpreters in all threads see the same data (though IIRC safe interpreters don't see the env array at all) and a change made by one can be seen by all. This makes access to the array quite slow, and I don't recall if there are cross-interpreter/cross-thread traces (though I suspect not, so you can't use it as an inter-thread communication mechanism. Use something designed for the task instead).
LV How does one code a check to see if an environment variable like DISPLAY is available? When I code:
if { [info exists $::env(DISPLAY) ] } { package require Tk }the application ceases because the variable doesn't exist.escargo This might be a question I can answer. Your code is doing two things:
- Retrieving the value of env(DISPLAY) in the global name space.
- Checking to see if the value exists.
if { [info exists ::env(DISPLAY) ] } { package require Tk }
How does one actually change an environment variable with Tcl, so that the change is reflected in the program's parent process/ parental shell in Windows?LV I don't do much on Windows, but most environments do not allow a child to modify a parent process (perhaps for security reasons, but certainly for stability reasons you don't want this to happen). About the best you could do is have the child write out a file that the parent, upon completion of the child, executes in its own process space to effect the change.More on this subject appears in "Setting environment variables with a script".
MG March 7th 2006 - One odd thing about the env array worth noting is that - at least for me on Win XP Home SP 2 - the var names are NOT case-sensitive. That is:
% parray env windir env(windir) = C:\WINDOWS % parray env WINDIRSo $env(windir) is set, and $env(WINDIR) is not. Then..
% set env(windir) C:\WINDOWS % set env(WINDIR) C:\WINDOWS % set env(WiNdIr) C:\WINDOWSAnd [info exists], etc., all report the var existing, no matter what case is used for the key name. I believe this is because the underlying OS does not treat environment variables in a case-sensitive manner, but I find it curious that although Tcl only sets them with one case (as per [array names] or [parray]), they can be accessed using any case.fredderic: I'm guessing the answer to that can be found also in DKF's comment:
- The env array is precisely the environment variables of the current process.
RS 2007-02-22: One can use temporary env variables to control a Tcl script from the command line, at least in Unixoid systems including Cygwin. Example scriptlet:
set foo 42 if [info exists env(DO)] {eval $env(DO)} puts foo=$fooThis script will typically report
foo=42To remote-control it without editing, set the DO variable before the call:
$ DO='set foo 4711' tclsh myscript.tclwhich will evidently report
foo=4711
LV 2007 June 21: Are there any env variables that are created by Tcl auto-magically? That is, certainly I understand that if in a script I execute a set command, I can create an env variable. But are there any that Tcl creates behind the scenes?
[Rahul] - 2009-09-30 04:25:58Hello....i am running tcl from my linux.(csh)....i need to send the value of a variable from tclsh top the parent shell...can anyone tell me if this is possible and if it is...suggest a way..:'(pcam I think this is probably not the best way to come about your issue. Have a read here [2] and here [3] and the posts seem to provide some guidance about a similar problem. What about you detail why you need to do this and I am sure someone will have advice on how to proceed, and I bet there is a way out.LV - 2009-09-30 08:46:06Since tclsh runs as a child to the parent, it cannot directly add a variable to the parent. There are several approaches that can be taken, but these involve some sort of interprocess communication.For instance, the parent could start the child, reading the child's stdout, and then create or update a variable based on information produced by the child.Or the parent could start the child, the child create a file, database table, shared memory/message queue/etc. containing the information needed, and then the parent read the created entity and set the variable itself.Or the child could start its own child, similar to the parent, but with the variable defined.Or the parent could listen to a socket, and the child then write to that socket to send along information.There are other such options. It is likely all follow the same pattern.snichols - 2010-03-17 12:30:00Here is a short Tcl script that generates a report of environment variables. I found the report useful when porting my build environment settings to a new computer.
global env foreach key [array names env] { puts "$key=$env($key)" }pw - 2010-09-03 14:20:00Here is an even shorter one ;)
parray ::envsnichols - 2010-11-7 11:17:00Clever one liner. Ran it, but can't copy the report into other programs such as batch files.
See also edit
- WINDIR on Windows
- COMSPEC on Windows
- HOMEPATH on Windows (also HOMEDRIVE)
- TZ on Windows
- PATHEXT on Windows
- CC
- HOME
- LANG
- LC_ALL
- LC_CTYPE
- PATH
- SHLIB_CFLAGS
- TCL_LIBRARY
- TCLLIBPATH
- TCLTEST_OPTIONS