Version 13 of Setting /bin/sh environment variables in the script

Updated 2002-07-27 10:16:04

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

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 <infile> <outfile>"
        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 process", according to the authoritative Unix Programming FAQ [L1 ] (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 ...