Shell Scripting for the System Administrator


Script Header

#!/bin/sh    <-- declaration of the full path to the shell to use for script execution

Script:  script_name.sh
Author:  First Last
Date:  <Date>

Modification History:  <Date>   <Who>  <Description>

Purpose:   Test to describe what this script does

Displaying Output

echo "This will be displayed on the screen"

$variable=yellow
echo "The color of the day is $variable"

ksh specific options:
print -u 2 "This will be displayed in a log file"  <--  If the script is executed with "./script.sh 2>log.file"
print -u 1 "This will be displayed on the screen"


Supressing the newline at the end of an echo statement:

\c will surpress the newline that is normally at the end of an echo statement.
echo "These 2 lines \c"
echo "will be displayed on a single line!"

Supressing the display of error messages:

command 2>/dev/null

2 is the standard error.  By redirecting 2 to /dev/null, then no error messages are displayed on the screen.

File Manipulation

basename - removes the directory from the full path and leaves the filename
dirname - removes the filename from the full path and leaves the directory

Loops

 For --> Do --> Done

for variable in $variable_list
do
     command
     command
     command
done

Example

fileList='/etc/issue /etc/motd /etc/ntp.conf /etc/nsswitch.conf /etc/profile'
for File in $fileList
do
        chown bin:bin $File
        chmod 444 $File
done

This script will change the ownership and change the file permissions (chown and chmod) on the five files listed in the fileList array.


While --> Do --> Done

while [Condition]
do
     command
     command
     command
done

Example

while true
do
ps -ef  | grep defun | grep -v grep
sleep 5
done

This script will check for zombie processes every 5 seconds until interrupted by <ctrl> <c>

Interrupting a Loop

exit

exit n  ---> n is the status code.  A status code of 0 indicates success.

Conditionals

if --> then

if [ expr ]      <-- note space after "[" and before "]"
then               <-- then must be on a separate line

    command 1
    command 2
    command N

fi

Example

if [ $? -ne 0 ] then
echo "Exit status is $?"
fi

if --> then  --> else

if [ expr ] then
     command 1
     command 2
     command N
else
     command 1
     command 2
     command N
fi



Shell Script Operator
Numeric
String
Equal
-eq
=
Not Equal
-ne
!=
Less Than
-lt

Less Than or Equal To
-le

Greater Than
-gt

Greater Than or Equal To
-ge

If the file exists
[ -f file ]
If the directory exists
[ -d directory ]
If the variable has a value
[ -z variable ]

System Variables

$?  -  exit status of last command run.  $?=0 for successful completion.
$1, $2, . . . - command line arguments
 $#  -  number of command line arguments
$* - contains all command line arguments
$$ - process id of current program
$0 - program name and path


${0##*/}  - name of executing script

shift - removes an argument from the command line ($*)
shift 1 - removes the first argument from the command line


Sending email from the script

<PATH TO SENDMAIL>/sendmail -f"source_user@source.com" dest_user@dest.com < $DATA_FILE

Using su in a script

su -l <user> -s <full path of shell> -c "<command>" < /dev/null
su -l better -s /bin/sh -c "whoami" < /dev/null

Using ftp from a script

#!/bin/sh
USER=<ftp user name>
PASSWD=<ftp user password>
ftp -n <server> <<END
user $USER $PASSWD
binary
put <file spec>
quit
END


Sample Scripts


Script to check for specific patches on a machine:

swlist -a state -l fileset > /roots/patches.txt
patchList='PHCO_23083 PHCO_24112 PHCO_25429 PHCO_26061 PHCO_23492 PHCO_23900 PHC
O_25526 PHCO_25887 PHCO_24839 PHCO_23909 PHKL_23423 PHKL_23335 PHKL_26233 PHKL_2
3275 PHNE_22722 PHNE_23950 PHNE_24035 PHNE_25184 PHSS_25789 PHSS_26493 PHSS_2578
8 PHSS_26492 PHSS_26493'
for patch in $patchList
do
        count=`grep -c $patch /roots/patches.txt`
        if [ $count -eq 0 ]
                then
                echo "$patch is missing."
        fi
done

Script to run a series of commands for each line in a file:

for filesystem in `cat /tmp/wte_filesystems.list`
do
    echo "$filesystem"
done


Command line script to run a repetitive command:

# while true
> do
> ps -ef|grep defun
> sleep 5
> done


Command line script to run on each file in a directory that starts with PH:

# for patch in `ls|grep PH`
> do
> swlist -l product | grep $patch
> done

Command line script to identify the volume groups that specific disks from an ioscan are in (in this case Hitachi/OPEN-E)

for hw in `ioscan -fnkC disk | grep "OPEN-E" | awk '{print $3}'`
do
        ioscan -fnH $hw|grep dev|awk '{print $1}'|xargs -i pvdisplay {}|grep -e "PV Name" -e "VG Name"
        echo " "
done

Command line script to run a command if the test is successful

<command> && <command>

For example, this will email me if a string is found in a directory listing:

ls | grep "string"  && mailx -s "Match found" billetter@networktechnologist.com