Synfire's Quick Guide to Linux

Shell Scripts (cont)

Conditional Statements

Bash has two forms of conditional statements available in scripting. Conditional Satements allow you to adapt your program to your needs depending on key elements that may change. The two conditional statements in the bash shell are the if statement and the case statement.

The IF Statement

This statement is set up to be human readible as possible. The basic format for the if statement is as follows:

if [ expression ]
then

commands1

elif [ expression2 ]
then

commands2

else

commands3

fi

This basically reads: "if `expression' is true `then' execute `commands' `elif'(expressed as else if) `expression2' is true `then' execute `commands2' else execute `commands3' end if.

So, what happens here is that the shell tests `expression' if expression is true then the shell executes commands1, but if the expression was false then elif tells the shell to test `expression2', once again if `expression2' is true then commands2 is executed, and if `expression2' is false then commands3 is executed before exiting the if statement. Note when using the if statement if the expression is false the commands are not executed and the shell check for an else or elif statement this continues until the evaluation turns up true, else always turns up true.

Now it is about time for an example. This example script is used to create a speedy shutdown proccess for linux:

#!/bin/bash

# bye - This script will either shutdown or restart your computer

reboot="-r"     # sets the -r flag
shutdown="-s"   # sets the -s flag

if [ "$#" -ne 1 ]   # makes sure that an argument was entered
then

echo "Usage: $0 [OPTION]"
echo "           -r reboot"
echo "       -s shutdown"

elsif [ "$1" = $reboot ]    # executes reboot command if the argument is -r
then

shutdown -r now

elsif [ "$1" = $shutdown ]  # executes a shutdown if the argument is -s
then

shutdown -h now

else        # if the argument is not -r, -s, or NULL then an error is
        # displayed
        
echo "Error: Option not available!"
echo "Usage: $0 [OPTION]"
echo "      -r  reboot"
echo "      -s  shutdown"

fi

The CASE Statement

The case statement allows you to compare a pattern with other patterns and execute certain commands if the pattern matches. The syntax for this is:
case pattern in

pattern1)

commands1;;

pattern2)

commands2;;

pattern3)

commands3;;

*)

commands4;;

esac
Now, pattern is compared to pattern1, pattern2, and pattern3. If pattern matches one of these the following commands are executed until it reaches the double semi-colons (;;). If none of the patterns match pattern then the commands after *) are executed until the double semi-colons. The *) pattern is a wildcard pattern. It will match any pattern. Always remember to end a case with esac.

(you may have noticed that in the if and case statements, to end them you simply type the word backwards "ie. if/fi and case/esac)

Remember the bye script we wrote with the if statement? Here it is again but this time it is using the case statement:
#!/bin/bash

# bye2 - This script will either shutdown or restart your computer

case "$1" in

-s)

shutdown -h now
;;

-r)

shutdown -r now
;;

*)

echo "Usage: $0 [OPTION]"
echo "      -r  reboot"
echo "      -s  shutdown"
;;

esac

Iteration Statements

An iteration statement is just a big name for a looping statement. a looping statement makes your program (or script in this case) repeat a section until a certain aspect is satified. The most common looping statement is the FOR statement. The syntax of the for statement is as follows:

for variable in list

do

commands

done
This form of the for statement executes `commands' for each item in the list. The list can be a variable with several words seperated by spaces, or a list of values inputed directly into the statement. Each time the statement loops `variable' is assigned the current value in the list. This is repeated until the last value is reached. Another version of the for loop is:
for variable

do

commands

done
This form executes commands for every item in variable. This form of the for loop by default, assumes that all argument passed on the command-line are given to variable. This is the same as writing:
for variable in "$@"

do

commands

done
Although this is the most used Iteration statement, I prefer to use the while statement whenever possible. The WHILE statement repeats the commands between do and done as long as long as the expression given is true:
while expression
do

commands

done
The examples previous to this one were ones I came up with myself, but this example is the best I have seen to illustrate the while loop, and since this example works I don't see a reason to "Recreate the Wheel" so to speak:
#!/bin/bash

# example-while.sh - This script list the parameters passed to the script
# in a numbered list

count=1

while [ -n "$*" ]

do

echo "$count .......... $1"

shift

count=`expr $count + 1`

done
This example does use commands that I haven't explained yet but, you should be able to get a good idea about how this works.

Another looping statement I like better than for is the until state- ment. This is the total opposite of the while statement. The sytax is the practically the same, but the until statement executes the commands as long as the expression is FALSE!

until expression
do

commands

done
If you really think about it, the until statement is really useless. anything you can write using an until statement you can alternatively write using the while statement. I leave wich one you want to use solely up to you. Just always remember that while tests for truth and until tests for false.

The Shift Command

Now that you have seen the shift command, I guess I should explain what the hell it is! Basically, shift moves the current values stored in the positional parameters (ie. $1,$ 2, $3...) one position to the left. Here is an example to clearify that for the technically declined ;) :
#!/bin/bash

# shift_example.sh - This script better explains the shift command

if [ $# -ne 1 ]
then

echo "Please enter three arguments on the command-line."

else

echo "arguments before shift $1 $2 $3"

shift

echo "arguments after shift $1 $2 $3"
echo "Does that explain what shift does better?"

fi
Shifts abilities doesn't stop there! You can actually specify how many times you want to move the positional parameters to the left by defining the amount as an argument to shift:

shift 3

This example would be the same as:

shift
shift
shift

This part of the shift command was added to keep the programmer from haveing to retype the shift command over and over again just to move a few arguments.

*******************************************************************************

As I said before this is a bash shell scripting tutorial, But I would like to add a little info on another shell called pdksh. All the commands that I have discussed apply to bash scripting and pdksh scripting. But here is a feature of pdksh that does not apply to bash. The reason why I'm telling you this is the fact that this is a kick ass command and it saves alot of typing. See to do what this pdksh command does in bash you would have to type alot of if/case statements and just as many while/until loops! This command is the SELECT statement. Here is the syntax:
select menuitem [in item1 item2 item3 item4]
do

echo "Are you sure you want $menuitem? [y/n] "

read yorn

if [ $yorn = "y" -o $yorn = "Y" ]

then

break

fi

done
The select command makes a numbered list of the items then lets the user select a menu option and stores the option chosen to the menuitem variable. If you want to practice on your bash scripting you could write a select program using bash and save it as "/usr/sbin/select" to give this option to your bash scripts. The syntax for executing select would be a bit different but it can be done! Trust me! ;)

********************************************************************************

Right about now you might be asking yourself "Why in the hell did he go into a pdksh statement on a tutorial about bash scripting?" The answer is simple. It gave me a chance to suggest an exercise for you to do, while at the same time allowed me you introduce two new commands. The first of the two is the `read' command. This allows a user to input information into the script from within the script! This is the best way to get away from command-line programs and get into more interactive programming! Here is how it works:

read variable

The read command waits for user input when the user types something everything the user types is saved into `variable'. Easy huh! OK now we go on to the second command introduced in the above script, the break command. The break command is used to exit a for, while, until, select, or repeat statements. (note: you won't be learning about repeat, it is a tcsh statement)

Functions-

Functions are probably the best aspect of the high-level programming world. Functions, or subroutines as called in Perl, are blocks of code that you write for organizational purposes, to make your scripts more human readable, and to make your scripts smaller, this is possible because instead of rewriting the same thing over and over everytime you need it you can write it once in a function and place a call to the function everytime you need it. The syntax for a function is:
function1 () {

commands

}
Once you have defined your function you can invoke, or call, it with this command:

function1 [param1 param2 param3 ...]

Notice that you can pass any number of parameters to your function. Think of a function as a script within a script. The parameters work just like the command-line arguments. This example demonstates this:
#!/bin/bash

# stronger.sh - This script strengthens your linux security
# You may need to edit this for it to work on your version.
# Tested on MDK 7.1, MDK 7.2, and MDK 8.0

if [[ -f /usr/share/msec/lib.sh]]; then
  . /usr/share/msec/lib.sh
else
echo "Couldn't find /usr/share/msec/lib.sh"
exit 1
fi

stack_overflow () {

echo "Stack Overflow                [SECURED]"
AddRules "/lib/libsafe.so.1.3" /etc/ld.so.preload

}

umask () {

echo "User Masks                [SECURED]"
AddRules "if [[ \${UID} == 0 ]]; then umask 022; else umask 077; fi"/etc/profile
AddRules "if [[ \${UID} == 0 ]]; then umask 022; else umask 077; fi"/etc/zprofile
AddRules "PATH=\$PATH:/usr/X11R6/bin:/usr/games" /etc/profile quiet
AddRules "export PATH SECURE_LEVEL" /etc/profile
AddRules "PATH=\$PATH:/usr/X11R6/bin:/usr/games" /etc/zprofile quiet
AddRules "export PATH SECURE_LEVEL" /etc/zprofile

}

while [ $choice -ne 3 ]
do

echo "What would you like to do?"
echo " "
echo "1.    Add User Mask Protection"
echo "2.    Add Stack Overflow Protection"
echo "3.    Exit
echo " "
echo "Enter a choice: "
read choice

if [ $choice -eq 1 ]
then

stack_overflow []

elif [ $choice -eq 2 ]
then

umask []

else

echo "Good-bye!"
exit 1

fi
This concludes the section on Shell Scripting. I suggest you read it about 3 or 4 times and learn it very well, because if you plan to use linux to to the best of it's power you will use scripting alot!!!

< < < Lesson 4.1: Shell Scripts part 1 | Lesson 5: Connecting to the internet > > >