What Are They? Why Use Them Example Useful Profiles Example Cron Test Function Example Raw Cron Test Example Setting User Environment Environment Example Environment Variables

Startup Files & Environment

Now lets just take a timeout from the syntax rules and have a quick look at startup files.

What Are They?

Start-up Files are files that are read by the script at the start of execution. There is a set of editable default files supplied with UNIX, or you can create you own and force the shell to read these instead, or indeed, as well as. Again there is a difference between C Shell and the rest. The C Shell will read two files by default at login, then one each time the C Shell is invoked. The files are .login and .cshrc (note the leading dot) and both files do not require their execution bit to be set. They are only read by the shell and the commands contained within the files are executed within the current shells' environment. It is in these files that environment variables usually get set. If you want to force another file to be read at shell start up, you can use the source command within a script thus:

	source .my_environment

Which will read the file .my_environment into the current shell and then execute the commands found just as if they had existed in the executing script.

For the sh & ksh there is only one default file called .profile and it is only run at login time. If you want a start-up file to be run at every execution of these shells, or at the start of any shell script, you must force it with the dot (.) command as shown below:

	.  .my_profile

Now this is what I call an abbreviation! It can be very easy to overlook such an innocent looking command, which is one reason I always include it as the first thing after the banner and give the read file such an obvious name. As my default environment is the C Shell, I just use .profile for the sh & ksh start-up files (yes they can and do share a common file - just put the fancy ksh specific stuff in a file that sh will not see). In all cases, nesting the start-up files is allowed and I am not aware of any nesting limits within reason.

Why Use Them?

Well, it's nice to know that when you call on previously written utilities from within a script, that they will be found. Paths therefor are a common feature of the start-up files. There are other bits of information that you may initially think are not so useful but are indeed called upon regularly from within scripts. The Example 10.2.1 shown below is a chunk from my own .profile to show some useful features which most of my other scripts rely on.

Example useful profiles

export COMPANY='ACME'
export THISHOST=`uname -n`
export MASTER_DB='mdb__001'
export SCRIPTS=/$COMPANY/$THISHOST/unix/cen/scripts
export SQL=$SCRIPTS/sql
export PRINTER='hplj5`
if [ `tty | grep -ci not` -eq 0 ]
then
	stty ERASE ^H
	TERM=SUN
fi

Here you see the export statement used before the setting of the variable, which has the effect of exporting the variable into the parent environment. On the second line there is a command called uname which is executed (by enclosing in back-quotes) with an option -n to give the name of the executing host machine. The output from this command is passed to the environment variable THISHOST. Then on line 4 you can see this same variable supplying its value in the setting of the SCRIPTS variable. This is then used to help set the SQL variable on the next line. There is a literal string 'ACME' on line 1, and another on lines 3 and 6 - indicated by the single forward facing quotes.

The actual .profile that I use is now in several parts for ease of editing. The parts are:

  • .profile Always called
  • .profile_functions Always called (now in 6 sub-files)
  • .profile_oracle Always called
  • .profile_paths Always called
  • .profile_cron Called from cron jobs only

The first file is called from within the script using the obvious call:

	.  $HOME/.profile

The .profile itself ends with three calls to .profile_functions, .profile_oracle, and .profile_paths. All cron job scripts contain a further call to .profile_cron which contains paths specific for the cron jobs and some additional security features that stop the cron scripts from being executed by a user.

A word of warning about start-up files. Don't put commands in here which will output things to the screen (echo, cat, etc.) unless it is for debugging purposes only. Output from the start-up files will interfere with rsh, ftp and most other remote access procedures. Output will also get sent to USER mail from a script run from the crontab (the UNIX batch queue). Now this is a useful feature because it can be used as an alert mechanism. But overloading the facility with all kinds of garbage messages from start-up files soon gets very annoying and eventually you will start deleting the mail before actually reading it, which is no good at all.

Also, if your one of those for whom the backspace key should deliver a <CTRL-H> character (as I am), then you no doubt have an stty erase ^H statement hanging around in your start-up files somewhere. Beware of tty and stty statements if there's a chance that a cron job will pick them up. The cron processor has no terminal, so references to terminal set-up statements can create disruptive messages in the USER mailbox from cron. The way I cope with this is to have a user defined function in my .profile_functions called s_is_cron() which contains the line:

	tty | grep -ci not

This function will return the value 0 for a script running with a terminal, and 1 for a cron script running in background. This can then be used in an if statement to protect several terminal commands as follows:

Example cron test function

if [ `s_is_cron` -eq 0 ]
then
	stty erase ^H
	set TERM=SUN
fi

This same example is tagged onto the end of Example 10.2.1 above but without relying on a function call. For the C Shell (where there is no function definition statement - another good reason not to use it) the equivalent syntax would be as shown in Example 10.2.3 below.

Example raw cron test

if ( `tty | grep -ci not` != 0 ) then
	stty erase ^H
	setenv TERM SUN
endif

Of course, if you are going to use functions, then you have to make sure that you load the definition of the function before you call it for use. Usually these personalised sections are placed last, and a good way to do this is to put it all in a separate file and call it last in the start-up sequence. I have my own personal file which contains my own set of aliases and other short-cuts. They are all in the file .my_defaults in my home directory. The first line of this file says source $PROJECT/.cshrc which picks up the departments defaults for this project, the rest of the file adds my own C Shell tweeks. Remembering of course that all the C Shell stuff will be forgotten as soon as a sh or ksh script starts in its own sub-shell.

Another trick when connecting to a shared account (Several DBA's may have shared access to the dba account for creating databases etc.) is to set your own personalised environment from the following test (shown in C Shell as it would appear in a shared .cshrc file):

Example setting user environment

#======================================
# Set Up Dave's Environment
#======================================
set dave_1 = `who am i | grep -c 'dwsun3'`
set dave_2 = `who am i | grep -c '19.123.123.123'`
set dave = `expr $dave_1 + $dave_2`
if ( $dave == 1 ) then
	stty erase ^H
	setenv EDITOR emacs
	setenv DISPLAY 19.123.123.123:0.0
	setenv PRINTER hplj2
endif

Depending on how Dave logged in, the who am i command will return either a machine name where Dave connected from, or the IP address if the local /etc/hosts file has no record of Dave's terminal to look up the name mapping. So one of the two variables will be set to one. Add them together and the next variable will always be set to one whenever Dave logs in. From here the test is simple and all Dave's personal settings can be set-up. For some real world examples of .profile and .cshrc files, see Appendix A which contains listings from my own system.

Environment:

As well as the variables you set yourself or export into the environment using the export command, there are some environment variables which get set when you launch or execute a sh script. We covered the special variables like $$ and the positional parameters ($digit) in Parameters, but there are some more. There is a set that you collect at login time from the system defaults and another set supplied by the shell, as it is invoked. Some of these can be updated by the shell, some cannot. The following list is the default set showing where they are set and their default values.

Example environment variables

  • HOME
  • Is set at login to your home directory and is used as the default argument for the cd command. This can be re-set.
  • PATH
  • The command search path is set at login and updated when a shell is invoked to reflect the path for that shell. This is volatile and can be updated unless the shell is restricted (usr/bin/rsh), in which case it is fixed.
  • CDPATH
  • The path of the cd command. Needed in case you screw up the PATH!
  • PS1, PS2
  • The primary and secondary prompt strings. Initialised by the shell. Can be revised if required (usually: root = #, user = $).
  • IFS
  • Internal Field Separators (normally space, tab and newline). The cut -d option temporarily changes the IFS for the duration of the cut command.
  • SHELL
  • If set and if the contents include the string rsh, shell will become the restricted shell (usr/bin/rsh).
  • SHACCT
  • If set to a filename writable by the user, the shell will write an account record in the file for each shell procedure executed.
  • MAIL
  • +
  • MAILPATH
  • +
  • MAILCHECK
  • Are all related to the mail system you are using. See the man pages for the mail command you are using for details.
  • LC_TYPE
  • +
  • LC_MESSAGE
  • Are related to the local language and character sets in use. They allow messages and codes to be displayed in the local language and character set.

The shell provides defaults for PATH, PS1, PS2, IFS, and MAILCHECK. While the user login service provides defaults for HOME and MAIL. The SHELL variable is not changeable at any time and is set at shell invocation time. The PATH variable becomes immutable if the SHELL contains a reference to the restricted shell. In the restricted shell certain other commands will also become unavailable, but which ones rather depends on your system administrator! Be nice and you may get a few more.

Home Next Preface Introduction Basic Shells Shell Syntax Built-In Commands Command Substitution Startup & Environment Pipes, Lists & Redirection Input & Output Using Files Design Considerations Functions Debugging Putting It All Together Appendix Code Examples
Page 207
This page was brought to you by rhreepe@injunea.demon.co.uk