Many folks work in a mixed Shell environment. To assist the un-enlightened, often a tcl or tk script is called from another shell. For example: #!/bin/sh #\ exec tclsh "$0" "$@" The "#\" gets skipped because /bin/sh thinks it is a comment. When the script calls itself with the "exec $0", Tcl reads the "#\" line as a continuation of a comment, and skips over it to the next line. The problem with this is that sometimes we get used to our personal environments, and our scripts break when someone else runs them. The good news is that the same idea works for other environmental variables. #!/bin/sh #\ PATH=${PATH}:/path/to/tclsh/and/wish #\ LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib #\ export PATH LD_LIBRARY_PATH #\ exec tclsh "$0" "$@" '''LH''' ---- To read a shell environment variable in your Tcl script, try doing something like this: global env set olddisplay $env(DISPLAY) set env(DISPLAY) unix:0 ---- [LV] wonders whethere this might be expressed as well in this fashion: set olddisplay $::env(DISPLAY) set $::env(DISPLAY) unix:0 and forget about global . You can check to see if the variable exists by doing something like: if [info exists env(VARNAME)] { # okay, it's there, use it set value $env(VARNAME) } else { # the environment var isn't set, use a default set value "the default value" } ---- There are some special [magic variables] relating to the shell environment. The program name is assigned to the global variable argv0 and any arguments to it are placed in the global variable argv as a list. The variable argc is set to the number of elements in the list argv. As an example: #! /usr/local/bin/tclsh if { $argc != 2 } { puts stderr "$argv0: Usage: $argv0 " exit 1 } set infile [lindex $argv 0] set outfile [lindex $argv 1] ---- For setting environment variables for exec'd processes: exec /usr/bin/env PATH=/usr/local/bin:${PATH} myprog Will work with all UNICES that I know about. -'''PSE''' ---- Also see [exec magic] for a discussion of issues regarding "$@" '''EE''' ---- [LV] Many times people come looking for a way to set an environment variable in such a way as to influence a parent process. This is, in generally, rather difficult to do. One generally solves this problem via cooperation - in some way communicating back to the parent process that it needs to set the variable itself. For example, you could write out to stdout the value you want the parent to get, then have the parent process read the child's stdout and put the value into the variable. Or you could write out a text file containing variable names and values (perhaps in shell format) then have the parent read in the values and take the action. Or you could set up some sort of socket, pipe, etc. and communciate that way. But at least in Unix like systems, a child process '''DOES NOT HAVE WRITE ACCESS''' to the process space of the parent. ''Period'' . [CL] puts it more starkly: "... you can't change the value of an environment variable in another already running process", according to the authoritative Unix Programming FAQ [http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC8] (why? Among other reasons, security considerations prohibit such an operation). However, as Larry hints above, there are ways to change the question slightly to give effective control over ... ---- '''SETTING ENVIRONMENT VARIABLES UNDER WINDOWS OS''' The following useful information was extracted from a thread that appeared in c.l.t.: '''--> 9-9-2002, Marty Backe''' writes: set ::env(MyVar) d:\Program Note that this will only effect child processes of the Tcl program that issues the command. '''--> 9-9-2002, Donal K. Fellows''' writes: Well, setting environment variables is easy. Just use the global 'env' array: set env(MyVar) {d:\Program} There are some things to watch out for. On windows, setting an env-var to the empty string deletes it (because that's how the platform operates.) And on all platforms, propagating env-var settings to the parent environment is non-trivial (i.e. requires cooperation from the parent, like executing code that is passed back to it); this restriction is important (for things like security) but is occasionally very annoying. (Also, if you want to put backslashes in variables, watch out for Tcl's quoting which can interact with it in some circumstances.) '''--> 10-9-2002, Tom Wilkason''' contributes recipes for setting environmental variables under MS Windows OS, which have a '''system wide''' scope: Under NT and beyond, you have a couple of choices. You can use the script below or exec the setx program that is part of the windows resource kit (a free download). Under Win9X I believe you will have to modify the autoexec.bat file and reboot. ;## ;# Set a system wide Env variable ;# proc setSysEnv {key value} { package require registry global env global InWidgets ;# Support OS expandable params if {$key == "PATH" || [string match "*%*" $value]} { # Indicate this may have expandable params in it set type expand_sz } else { set type sz } if {[catch { if {[catch { registry set \ "HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Control\\Session Manager\\Environment" $key $value $type registry set \ "HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet002\\Control\\Session Manager\\Environment" $key $value $type registry set \ "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment" $key $value $type } result]} { catch {registry set "HKEY_CURRENT_USER\\Environment" $key $type} } else { catch {registry delete "HKEY_CURRENT_USER\\Environment" $key} } set env($key) $value } result]} { tk_messageBox -title "OK to Continue" -icon info \ -message "Error setting env var $key to $value, do you have admin priviledges?\n$result" } }