Sei sulla pagina 1di 10

Shell Programming Standards

GEHC Offshore DBA Team

Classification: Wissen-GE Internal

Table on Contents

Shell Programming Standards...................................1


Overview................................................................................................................3
Korn Shell..............................................................................................................3
File Names.............................................................................................................3
File Suffixes.........................................................................................................................3
Specific Guidelines.............................................................................................................4
File Header.............................................................................................................4
Usage.....................................................................................................................4
Indentation.............................................................................................................5
Line Length..........................................................................................................................5
Wrapping Lines...................................................................................................................5
Commenting your work........................................................................................5
Implementation Comment Formats..................................................................................5
Block Comments...............................................................................................................5
Single-Line Comments......................................................................................................6
White Space...........................................................................................................6
Naming Conventions............................................................................................6
Error checking.......................................................................................................6
CRON job paranoia.............................................................................................................7
Summary of positive features.............................................................................8
Sample Code.........................................................................................................8

________________________________________________________________________
WISSEN internal
2

Overview
The GEHC Shell Programming Coding Standards were written by Offshore DBA Team and reviewed
and approved by Onsite DBA Team, as part of their efforts to make the GEHC system clean,
consistent, and easy to manage. This document can also be read as a guide to writing portable,
robust and reliable programs. Though it focusses on programs written in shell, many of the rules and
principles are useful for scripting in any other programming language. The rules often state reasons
for writing in a certain way.
We have to emphasize that a standard, being a "rallying point", is an essential means of
communication for the members of the team involved in the development of the project. Standards
help members of a team speak the same language.
Corrections or suggestions regarding this document should be sent to dbaodc@med.ge.com. If you
make a suggestion, please include a suggested new wording for it.
Point to remember before anything::
All Unix shells are case sensitive.

Korn Shell
GEHC DBA should write their code in Korn Shell. The KornShell language is a complete, powerful,
high-level programming language for writing applications, often more easily and quickly than with
other high-level languages. KSH has the best features of both, plus many new features of its own.
Thus ksh can do much to enhance your productivity and the quality of your work, both in interacting
with the system, and in programming.
The new version of ksh has the functionality of other scripting languages such as awk, icon, perl,
rexx, and tcl. For this and many other reasons, ksh is a much better scripting language than any of
the other popular shells. The code size for ksh is larger than the Bourne shell or C shell programs.
The revised version is even larger.
In spite of its increased size, ksh provides better performance. You can write programs to run faster
with ksh than with either the Bourne shell or the C shell, sometimes an order of magnitude faster. ksh
has evolved and matured with extensive user feedback
For using the KORN shell in your code, you need to put the following line at the beginning of your
shell program:
#!/usr/bin/ksh.

File Names
This section discusses the naming conventions to be followed while naming the shell programs. File
names are made up of a base name, period and suffix. The first character of the name should be a
letter and all characters (except the period) should be lower-case letters and numbers. The base
name should be 16 or fewer characters and the suffix should be two characters.

________________________________________________________________________
WISSEN internal
3

File Suffixes
Use .sh as a file suffix.

Specific Guidelines

Note that file names, and file extensions cannot contain uppercase letters, spaces, or special
characters (e.g., & or $), but may contain letters, numbers, underscores, and dashes.
Make sure that file names clearly denote their content.
Names must be as logical and clear as possible and make sense to people not familiar with
environment. Use unabbreviated words or common acronyms. They should be easy to
remember and easy to spell: e.g., geothermal, not geothrm.
Avoid overly general file and directory names (e.g., file1.sh, file2.sh). File names should be
based on the job it does.
Files longer than 1000 lines are cumbersome and should be avoided.
Avoid using reserved words or command names for file names. For example test should not
be used for file name.

File Header
Please add the following details at the beginning of the program.
Name:
Name of the script
Author:
Who wrote the script?
Date:
Date written
Description: Explain the purpose of the script
Revision History: This section should contain history of the changes to the script. Maintain the
history after this is tested thoroughly and implemented in production.

Here is the example:


# Name:
schema_refresh.sh
# Author:
Ashok K.Thatipally
# Date:
7/8/2005
# Description:This script is used to refresh target schema from a source schema. This script is
designed to run via Appworx.
#Revision History:
#Date
Who changed?

Actual Change

Usage
If the script needs to pass some arguments, then the usage of the script must be specified as follows.
usage()
{
print "usage: backup_balancing.sh [-h] [-d DATABASE_NAME] "

________________________________________________________________________
WISSEN internal
4

print "where: -h
help, usage"
print "
-d Database Name"
exit $1
}
if [[ $# < 2 ]]
then
usage 1
fi

Indentation
Four spaces should be used as the unit of indentation. The exact construction of the indentation
(Spaces vs. tabs) is unspecified. Tabs must be set exactly every 8 spaces (not 4).

Line Length
Avoid lines longer than 80 characters, since theyre not handled well by many terminals and tools.

Wrapping Lines
When an expression will not fit on a single line, break it according to these general principles:

Break after a comma.


Break before an operator.
Prefer higher-level breaks to lower-level breaks.
Align the new line with the beginning of the expression at the same level on the previous line.
If the above rules lead to confusing code or to code thats squished up against the right
margin, just indent 8 spaces instead.

Commenting your work


Comments should be used to give overviews of code and provide additional information that is
not readily available in the code itself. Comments should contain only information that is relevant to
reading and understanding the program.
Discussions of non-trivial or non-obvious design decisions are appropriate, but avoid duplicating
information that is present in (and clear from) the code. It is too easy for redundant comments to get
out of date. In general, avoid any comments that are likely to get out of date as the code evolves.
Note: The frequency of comments sometimes reflects poor quality of code. When you feel compelled
to add a comment, consider rewriting the code to make it clearer. Comments should not be enclosed
in large boxes drawn with asterisks or other characters. Comments should never include special
characters such as form-feed and backspace.

Implementation Comment Formats


________________________________________________________________________
WISSEN internal
5

Programs can have four styles of implementation comments: block, single-line, trailing and end-ofline.

Block Comments
Block comments are used to provide descriptions of functions. Block comments may be used at the
beginning of each file and before each function. They can also be used in other places, such as within
sub programs. Block comments inside a function should be indented to the same level as the code
they describe. A blank line to set it apart from the rest of the code should precede a block comment.
#
#Hereisablockcomment.
#

Single-Line Comments
Short comments can appear on a single line indented to the level of the code that follows. If a
comment cant be written in a single line, it should follow the block comment format (see above). A
blank line should precede a single-line comment. Heres an example of a single-line comment:
if[condition]then
/*Handlethecondition.*/
...
fi

White Space
Blank lines improve readability by setting off sections of code that are logically related. Two blank
lines should always be between sections of a code

Naming Conventions
Naming conventions make programs more understandable by making them easier to read. They can
also give information about the function of the identifier.

Use UPPERCASE for variables.

Error checking
If you are using scripts to check on important systems, or perform crucial functions, it is very
important to provide feedback to the calling process when and if something goes wrong.
The simplest method of doing this, is a simple
return1
# (But it would be nice to print out SOME message before returning control to main!)

________________________________________________________________________
WISSEN internal
6

Nice programs will notice that your script exited with a non-zero status. [Remember, the status of the
last command is in '$?']
Ideally, they will complain.
On the other hand, sometimes your own scripts are the ones that are doing the calling!
In that type of situation, it may be suitable to have a top-level script that keeps an eye on things. A
simple example is:
fatal(){
# Something went horribly wrong.
# print out an errormessage if provided, then exit with an
# "error" status
if [[ "$1" = "" ]] ; then
print Something went horribly wrong with "$1"
return 1
fi
# You may also want to SEND EMAIL, or trigger a PAGER or
# something here:
# mailx -s "Arrrg! we failed checks!" admin@yourhost.com < /dev/null
#
print ok
return
}
check_on_modems
if [[ $? -ne 0 ]] ; then

fatal modems ; fi

check_on_network
if [[ $? -ne 0 ]] ; then

fatal network ; fi

check_on_servers
if [[ $? -ne 0 ]] ; then

fatal servers ; fi

Note that even my paranoid 'fatal' function, IS PARANOID!


Normally, it is assumed you will call it with "fatal what-failed". But if you somehow dont, it notices, and
provides a default.
Sometimes, making the assumption that $1 contains valid data can completely screw up the rest of
your function or script. So if it is an important function, assume nothing!

CRON job paranoia


If you are coding a script that specifically is in a cronjob, there are two things to be aware of. The
number one, most important thing is; Set your PATH variable!!!
People always forget this one. It doesnt matter what is in your .profile, cron will reset the PATH
variable to something really short and stupid, like just /usr/bin. So set your PATH=/whatever:/usr/bin
explicitly in your cron scripts.

________________________________________________________________________
WISSEN internal
7

The second tip is more an advisory note.


CRON by default saves anything that gets send to 'stderr', and MAILS IT to the owner of the cron job.
So, sometimes, if you just want a minor error logged somewhere, it is sufficient to just do
print "Hey, this is kinda wierd" >/dev/fd/2
Which will send the output of the print to stderr, which will then go to email. Another way of doing it, if
your system does not have /dev/fd, could be
print "Wow, this is torture" 1>&2
Contrariwise, if you want to throw away ALL output, use
command >/dev/null 2>&1
If you do not regularly read email for the user in question, you can either set up an alias for that user,
to forward all its email to you, or do
export MAILTO=my@med.ge.com.here
The MAILTO trick does not work on all cron demons, however.

Summary of positive features


Here is a summary of all the positives added through the different versions.

Comment your scripts


Check for user-environment variables, where appropriate
When setting/overriding special variables, do it at the top of the script, in a unified place
Accept one OR MORE files, when it makes sense to do so.
Have a "usage" message
Be Paranoid: check return statuses
Return correct statuses yourself: ("exit 1", vs. "exit")
Take advantage of 'getopts' when adding optional functionality
#!/bin/ksh

Sample Code
# Name:
schema_refresh.sh
# Author:
Ashok K.Thatipally
# Date: 7/8/2005
# Description: Sample Code - editing wrapper
#Revision History:
#Date
Who changed?

Actual Change

# Usage: see usage() function, below


usage(){
print sedit - a wrapper to edit files under SCCS
print "Usage: sedit [-c|-C] [-f] file {file2 ...}"

________________________________________________________________________
WISSEN internal
8

print " -c check in file(s) after edit is complete"


print " -C check in all files with single revision message"
print " -f ignore errors in checkout"
}
# Set EDITOR var to "vi" if not already set to something
EDITOR=${EDITOR:-vi}
# Could already be in path, but it doesnt hurt to add it again.
# Sorry, I assume solaris machines everywhere: adjust as needed.
PATH=$PATH:/usr/ccs/bin
if [ ! -x /usr/ccs/bin/sccs ] ; then
print ERROR: sccs not installed on this machine. Cannot continue.
usage
exit 1
fi
while getopts "cCfh" arg
do
case $arg in
c)
checkin="yes"
;;
C)
checkinall="yes"
;;
f)
force="yes"
;;
h|*)
usage
exit 1
;;
esac
done
shift $(($OPTIND - 1))
if [ $# -lt 1 ] ; then
usage
print ERROR: no files specified
exit 1
fi
if [ "$checkinall" != "" ] && [ "$checkin" != "" ] ; then
print WARNING: -c and -C used. Will use C.
fi
# Yes, I could use "sccs edit $@" and check for a single error, but this
# approach allows for finer error reporting.
# "$@" is a special construct that catches spaces in filenames.
# Note that "$*" is NOT 100% the same thing.
for f in "$@" ; do
sccs edit "$f"
if [ $? -ne 0 ] ; then
print ERROR checking out file $f
if [ "$force" = "" ] ; then

________________________________________________________________________
WISSEN internal
9

if [ "$filelist" != "" ] ; then


print "Have checked out $filelist"
fi
exit 1
fi
# else, -f is in effect. Keep going
fi
filelist="$filelist $f"
done
# I would like to use "$filelist", but that does not preserve spaces
# in file names
$EDITOR "$@"
if [ $? -eq 0 ] ; then
print ERROR: $EDITOR returned error status
exit 1
fi
if [ "$checkinall" != "" ] ; then
# -C option used. re-check in all files at once.
sccs delget $filelist
if [ $? -ne 0 ] ; then
print "ERROR checking in files?"
exit 1
fi
exit 0
fi
if [ "$checkin" != "" ] ; then
# -c option used. re-check in each file.
for file in $filelist ; do
sccs delget $file
if [ $? -ne 0 ] ; then
print "WARNING: failed to check in $file"
fi
# do NOT stop after error. Keep trying to check
# in any other files
done
fi

________________________________________________________________________
WISSEN internal
10

Potrebbero piacerti anche