Shell Scripting and PATHs

Everseen a PATH like this....

/opt/sybase/ASE-12.5/bin:/opt/sybase/ASE-12.5/install:/usr/local/bin:/opt/sybase/ASE-12.5/bin\\
:/opt/sybase/ASE-12.5/install:/usr/local/bin:/usr/bin:/bin

I have over the last couple of weeks been installing Users on UNIX systems and considering the issue of the PATH variable. The PATH above is caused by not checking if the directory is in the PATH, before adding it. This is particulalry a problem for those shells that have one file executed on a login and one file executed each time a new shell is invoked, such as ksh & bash. Also, for users created to own shared services (such as sybase in this case), people may enter the user from several entry points, including login, su \* su -. The problem is exacerbated when the environment definitions are written by a third party, in this case Sybase, but other packages have their own problems.

I have decided to undertake a test prior to amending the path. I'd like to write a function 'prepend2path, but came to the conclusion that the level of indirection required was to much, for me at least. I use a function contains

contains()
{
    #contains $PATH $directory
    /usr/bin/echo $1 | /usr/bin/grep $2 > /dev/null
    return $?
}

This allows me to test if a $PATH contains a given $directory

  if [ -d ${directory} ]
  then
      contains $PATH $directory
      if [ $? !=0 ]
      then
          PATH=${directory}:${PATH}
      fi
  fi

These statements should probably be placed in the shell read configuration file for the default login shell for the user, however they may be located elsewhere for good reason, such as in a script so that it can be run from wherever and the script becomes responsible for obtaining its own environment. The function can be placed in an external functions file and then invoked from wherever should this seem sensible.

This code model can be used for LD_LIBRARY_PATH and MANPATH. Both these variables may be unset so the contains function needs to OR'd with -z test. Also we can iterate the test.

  for directory in ${STEM}/install ${STEM}/bin
  do
    if [ -d ${directory} ]
    then
        contains $PATH $directory
        if [ $? !=0 ]
        then
          PATH=${directory}:${PATH}
        fi
    fi
  done

As I write this article, it becomes clear I should put the -d test inside the contains function.

contains()
{
    #contains $PATH $directory
    if [ -d $directory];then
        /usr/bin/echo $1 | /usr/bin/grep $2 > /dev/null
        return $?
    else
        return 99
    fi
}

This leaves the path assignment statement looking like this.

  for directory in ${STEM}/install ${STEM}/bin
  do
    contains $PATH $directory
    if [ $? !=0 ]
    then
      PATH=${directory}:${PATH}
    fi
  done

Of course there are those that say if you don't echo $PATH, you don't have the problem either!

tags:

Comments:

Post a Comment:
Comments are closed for this entry.
About

DaveLevy

Search

Archives
« July 2014
MonTueWedThuFriSatSun
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
   
       
Today