天天看点

shell常用语句总结

流控制:

if、then、else语句提供条件测试。测试可以基于各种条件。例如文件的权限,长度,数值等

case语句允许匹配模式,单词或值。一旦模式或值匹配,就可以基于这个匹配条件做其它声明。

循环

for循环 每次处理依次列表内信息,直至循环耗尽。

until循环 此循环语句不常用,until循环直到条件为真,条件部分在循环末尾部分。

while循环 些循环当条件为真时,循环执行,条件部分在循环头。

流控制语句的任何循环均可嵌套使用,例如可以在一个for循环中嵌入另一个for循环

IF THEN ELSE语句

if语句测试条件,测试条件返回真或假后,可相应执行一系列语句,if语句结构对错误检查非常有用

if 条件1

then 命令1

elif 条件2

then 命令2

else 命令3

fi

让我们来具体讲解if语句的各部分功能

=========================================

if 条件1 //如果条件1为真

then //那么

命令1 //执行命令1

elif 条件2 //如果条件1不成立

命令2 //执行命令2

else //如果条件1,2均不成立

命令3 //那么执行命令3

fi //结束

if语句必须以单词fi终止,esif和else为可选项,如果语句中没有否则部分,那么就不需要elif和else

最简单的if语句

if 条件

then 命令

使用if语句时,必须将then部分放在新行,否则会产生错误。如果不要分行,必须使用命令分隔符

可以使用以下格式

if 条件; then

命令

then不换行,必须要在其前面一句结束处加;号

以下是一个小脚本

==================================================

[root@localhost Shell]# more iftest.sh

#/bin/bash

#ScriptName iftest

#This is a comment line, all comment lines start with a #

if [ "10" -lt "13" ]; then

# yes,10 is less than 13

echo "Yes,10 is less than 13"

执行结果为

[root@localhost Shell]# sh iftest.sh

Yes,10 is less than 13

再来一个例子看下

[root@localhost Shell]# more iftest2.sh

#!/bin/bash

#ScriptName iftest2

echo -n "Please enter you name: "

read name

if [ "$name" = "" ]; then

echo "You did enter any information!"

else

echo "You name is : $name"

执行结果

[root@localhost Shell]# sh iftest2.sh

Please enter you name: LinuxShell

You name is : LinuxShell

Please enter you name:

You did enter any information!

[root@localhost /]# cat ifpwd.sh

#ScriptName ifpwd

DIRECTORY=`pwd`

if [ "$DIRECTORY" != "/" ]; then

echo "You need to be in the root directory not $DIRECTORY to run this script" >&2

exit 1

===============================================================

运行结果

[root@localhost Shell]# sh ifpwd.sh

You need to be in the root directory not /root/Shell to run this script

[root@localhost Shell]# cp ifpwd.sh /

[root@localhost Shell]# cd /

[root@localhost /]# sh ifpwd.sh

测试传递到脚本中的参数个数

if语句可用来测试传入脚本中参数的个数,使用特定变量$#,表示调用参数的个数。

以下测试确保脚本有三个参数,如果没有,刚返回一个可用信息到标准错误,然后代码退出并显示退出

状态。如果参数数目等于3,则显示所有参数。

================================================================

[root@localhost Shell]# cat -n ifparam.sh

1 #!/bin/bash

2 #ScriptName ifparam

3 if [ $# -lt 3 ]; then

4 echo "Usage: $0 arg1 arg2 arg3" >&2

5 exit 1

6 fi

7 echo "arg1: $1"

8 echo "arg2: $2"

9 echo "arg3: $3"

[root@localhost Shell]# sh ifparam.sh John Smith

Usage: ifparam.sh arg1 arg2 arg3

下面给3个参数

[root@localhost Shell]# sh ifparam.sh John Smith Tom

arg1: John

arg2: Smith

arg3: Tom

测试目录创建结果

创建一个目录,如果没有输入创建目录的名字,那么提示用法。如果目录已经存在,那么什么都不做

如果目录不存在,则提示目录不存在,是否创建,创建输入y不创建输入n

脚本如下

[root@localhost Shell]# more ifmkdir.sh

#ScriptName

DIRECTORY=$1

if [ "$DIRTCTORY" = "" ]

then

echo "Usage : $0 directory to create." >&2

if [ -d $DIRECTORY ]

then :

else

echo "The directory does exists"

echo -n "Create it now?[y..n]:"

read ANS

if [ "$ANS" = "y" ] || [ "$ANS" = "Y" ]

echo "Createing now."

mkdir $DIRECTORY >/dev/null 2>&1

if [ $? != 0 ]; then

echo "Errors createing the diryctory $DIRECTORY" >&2

else :

以下为执行结果。

[root@localhost Shell]# sh ifmkdir.sh

Usage : ifmkdir.sh directory to create.

[root@localhost Shell]# sh ifmkdir.sh LinuxShell

The directory does exists

Create it now?[y..n]:y

Createing now.

[root@localhost Shell]# ls

LinuxShell father.sh grepstr.sh ifdirsc.sh ifparam.sh iftest.sh param.sh

child.sh findfile.sh hello.sh.bak ifeditor.sh ifpwd.sh iftest2.sh

data.file grepif.sh ifcp.sh ifmkdir.sh ifroot.sh ifwr.sh

多个IF语句

看下面一个脚本

=============================================================================

[root@localhost Shell]# cat ifseted.sh

#ScriptName ifseted.sh

#Author:Honway

#Date:2011-08-09

if [ -z $EDITOR ]; then

echo "Your EDITOR environment is not set."

echo "I Will assume you want to use vi..OK"

echo -n "DO you wish to chang is now? [y..n]:"

if [ "$ANS" = "Y" ] || [ "$ANS" = "y" ]; then

echo -n "enter you editor type:"

read EDITOR

if [ -z "$EDITOR" ] || [ "$EDITOR" = "" ]; then

echo "No editor entered,Using vi as default."

EDITOR=vi

export EDITOR

fi

EDITOR=$EDITOR

export EDITOR

echo "Setting $EDITOR"

echo "Using vi as the default editor"

EDITOR=vi

设置默认编辑器,开始的时候,检查有没有设置默认编辑器。如果为空,那么会提示用户

然后给出一个选择,是不是现在要设置,是的话输入Y否则输入N,不管输入的是大Y还是小Y

都提示用户输入编辑器类型。如果没有输入,那么就设置为VI,如果输入,就用用户输入的

编辑器作为默认编辑器。如果在上一步用户输入N,那么使用VI作为默认编辑器

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

*** CASE语句 ***

case语句为多选语句。可以用case语句匹配一个值与一个模式。如果匹配成功,执行相匹配命令

======================================

case语句格式:

case 值 in

模式1)

命令1

;;

模式2)

命令2

esac

case工作方式如上。取值后面必须为单词in,每一模式必须以右括号结束。取值可以为变量或常数

匹配发现取值符合某一模式后,其间所有命令开始执行直到遇到符号;;结束

取值将检测匹配的每一个模式。一旦模式匹配,则执行完匹配模式相应命令后不再继续其他模式。

如果无一匹配模式。使用星号*捕获该值,再接受其它输入。

模式部分可能包括元字符,与在命令行文件扩展名例子中使用过的匹配模式类型相同,即:

=========================

* 任意字符

? 任意单字符

[..] 类或范围中任意字符

==========================

看一个小脚本先

====================================================

#ScriptName caseselect

#DATE:2011-08-10

echo -n "Enter a number from 1-5 :"

case $ANS in

1) echo "You select 1"

;;

2) echo "You select 2"

3) echo "You select 3"

4) echo "You select 4"

5) echo "You select 5"

*) echo "$0 : This is not between 1 and 5."

很简单,不解释。

再来一脚本例子

#ScriptName caseterm

echo "Choices are .. vt100,vt102,vt220."

echo -n "Enter your terminal type: "

read TERMINAL

case $TERMINAL in

vt100|vt102) TERM=vt100

vt220) TERM=vt220

*) echo "$0 : Unknow response"

echo "Seting it to vt100 anyway,so there."

TERM=vt100

export TERM

echo "Your terminal is set to $TERM"

这个也没什么特别,就是说明了可以用|来代替或命令.

==

再来一脚本

#caseans

echo -n "Do you wish to proceed [y..n] :"

y|Y|yes|Yes) echo "Yes is selected "

n|N|no|No) echo "No is selected. "

exit 0 #No error so only use exit 0 to terminate

*) echo "$0 : Unknow response" >&2

跟上面的脚本一样,只是说明|可以代替或命令

捕获输入并执行空命令

不一定要在匹配模式后加入命令,如果你原本不想做什么,只是在进一步处理前过滤出意外

如果要运行对应于一个会计部门的帐目报表,必须首先决定运行报表的类型前确认用户输入一个

有效的部门号,匹配所有可能值,其它值 无效。用case可以很容易实现

下面的脚本中如果用户输入部门号不是234,453,655或454,用户退出并返回可用信息。一旦

响应了用户的有效部门号,脚本就用同样的技术取得报表类型。

=============================================================

TYPE=""

echo -n "Enter the account dept NO. :"

read ACC

case $ACC in

234);;

453);;

655);;

454);;

*) echo "$0 : Unkonw dept NO:" >&2

echo "Try.. 234,453,655,454"

echo " 1. post"

echo " 2. prior"

echo -n "Enter the type of report: "

read ACC_TYPE

case $ACC_TYPE in

1) TYPE=post;;

2)TYPE=prior;;

*) echo "$0 : Unkonw account type. " >&2

echo "Now running report for dept $ACC for the type $TYPE"

缺省变量值

如果在读变量时输入回车键,不一定总是退出脚本,可以先测试是否已设置了变量,如果未设置,可以

设置该值。

下面脚本中,要求用户输入运行报表日期。如果用户输入回车键,则使用缺省日期星期六,并设置为WHEN

的取值。如果用户输入另外一天,这一天对于CASE语句是运行的有交日期,即星期六,星期四,星期一

=====================================================

#ScriptName caserep

echo "--===============================--"

echo " Weekly Report "

echo -n "What day do you want to run report [Saturday]: "

read WHEN

echo "Validating..${WHEN:="Saturday"}"

case $WHEN in

Monday|MONDAY|mon)

Sunday|SUNDAY|sun)

Saturday|SATURDAY|SAT)

*) echo "Are you nuts! this report can only be run on " >&2

echo " on a Saturday,Sunday or Monday " >&2

echo "Report to run on $WHEN"

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

****** FOR循环 ******

for循环一般格式为:

---============================---

for 变量名 in 列表

do

命令2...

done

当变量值在列表里,for循环即执行一次所有命令,使用变量名访问列表中取值,命令可为

任何有交的shell命令和语句。变量名为任何单词。in列表用法是可选的,如果不用它,for循环使用

命令行的位置参数

in列表可以包含替换,字符串和文件名。

一个简单的for循环

#ScriptName for_i

for loop in 1 2 3 4 5

echo $loop

上面的脚本,变量loop在列表1 2 3 4 5中,等于是把1 2 3 4 5五个值赋给了loop.然后依次打印

[root@localhost Shell]# sh for_i.sh

1

2

3

4

5

打印字符串列表

下面for循环中,列表包含字符串"Orange Red Blue Grey",命令为echo,变量名为loop,echo命令使用

$loop反馈出列表中所有取值,直到列表为空

[root@localhost Shell]# cat forlist.sh

#ScriptName forlist

for loop in Orange Red Blue Grey

do

echo $loop

[root@localhost Shell]# sh forlist.sh

Orange

Red

Blue

Grey

看下跟下面的有什么区别

for loop in "Orange Red Blue Grey"

Orange Red Blue Grey

脚本中多了个双引号"",用双引号引起来,值相当于是一个,然后会被echo一下输出。

对for循环使用ls命令

这个循环执行ls命令,打印当前目录下所有文件

[root@localhost Shell]# cat forls.sh

#ScriptName forls

for loop in `ls`

[root@localhost Shell]# sh forls.sh

LinuxShell

caseans.sh

caseparam.sh

caserep.sh

caseselect.sh

caseterm.sh

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

对for循环使用参数

在for循环中省去in列表选项时,它将接受命令行位置参数作为参数。实际上即指明:

for params in "$@"

for params in "$*"

""号可以省略,其实最好省略(个人实践中发现。)

下面的例子不使用in列表选项,for循环查看特定参数$@或$*,以从命令行中取得参数。

---==================================---

#forparam2

for params

echo "You supplied $params as a command line option"

[root@localhost Shell]# sh forparam2.sh John Smith Tom Gim Kite

You supplied John as a command line option

You supplied Smith as a command line option

You supplied Tom as a command line option

You supplied Gim as a command line option

You supplied Kite as a command line option

每一个参数,都被打印出来了。

---================================================---

[root@localhost Shell]# cat forparam3.sh

#ScriptName forparam3

for params in "$@"

echo "You supplied $params as a command line option"

[root@localhost Shell]# sh forparam3.sh John Tom Cat Dog God

You supplied Cat as a command line option

You supplied Dog as a command line option

You supplied God as a command line option

[root@localhost Shell]# cat forparam4.sh

#ScriptName forparam4

for params in "$*"

echo "You supplied $params as a commad line option"

[root@localhost Shell]# sh forparam4.sh God Girl John

You supplied God Girl John as a commad line option

在使用$*的时候,如果想让结果输出多行。那么应该把""去掉,如下

for params in $*

[root@localhost Shell]# sh forparam4.sh Dog God

You supplied Dog as a commad line option

You supplied God as a commad line option

由上,推出一个查找文件的小脚本。内容如下:

#ScriptName forfind

for loop in $* //同上,in $* 或者$@ 或者省略in表示传递参数

find / -name $loop -print // -print可省略

使用for循环连接服务器

#ScriptName forping

HOSTS=192.168.2.1

for loop in $HOSTS

ping -c 2 $loop

#ScriptName forssh

#AUTHOR: Honway

#DATE:2011-08-11

echo -n "Please enter your server's IP [default ip:localhost] :"

read IP

echo -n "Please enter your server's port[defaul port:22] : "

read PORT

echo -n "Please enter your username[default user:root] :"

read USERNAME

echo "Start connecting $IP........ "

echo "Please waiting...."

ssh ${USERNAME:=root}@${IP:=localhost} -p ${PORT:=22}

多文件转换

#ScriptName forUC

for files in `ls *.sh`

cat $files | tr "[a-z]" "[A-Z]" >$files.UC

在当前目录查找所有.sh文件,然后把文件里的字母转换为大写字母,最后把转换后的结果写入到

当前文件名后面加.UC的文件中

删除所有指定文件类型中的空行

#Forsed

sed -e "/^$/d" $files >$files.HOLD

mv $files.HOLD $files

删除所有.sh文件中的空行,这里有一个mv命令,如果在系统中直接运行mv,并且同名文件存在,会有

提示信息,但是脚本里面确没有。我们输入alias看到,mv ='m -i' ,所以我们运行时才有提示信息

如果把别名去掉,就没有了。那现在问题就很明显了,脚本里执行的时候,没有调用父Shell里的别名

循环计数

我们用for来计算当前目录的所有文件数

#forcount

counter=0

for files in *

counter=`expr $counter + 1`

done

echo "There are $counter files in `pwd` we do need to process"

+1是为了统计的时候,加上这个脚本本身。

利用for循环,给所有当前在线的用户发送一封邮件

#ScriptName formailit

WHO_ON=`who -u | awk '{print $1}'`

for user in $WHO_ON

mail $user <<MAYDAY

Dear Colleagues,

It's my birthday today, see you down the club

at 17:30 for a drint

See ya.

$LOGNAME

MAYDAY

<<MAYDAY 以MAYDAY开始写一段内容,直到遇到MAYDAY关键字,才会结束,并且不在当地保存。

执行后的结果,看用户的邮件

To: [email protected]

root

=============================

===== for循环嵌套 =====

嵌套循环的格式:

for 变量名1 in 列表1

for 变量2 in 列表2

done

上脚本了

=====================================================================

#ScriptName for_for_loop

APPS="/usr/local/mysql /usr/local/apache2 /usr/local/php5"

SCRIPTS="report.sh cleanup.sh forloop.sh"

LOGFILE=for_for_loop.log

MY_DATE="`date +%H:%M` on `date +%Y-%m-%d`"

for loop in $APPS

for loop2 in $SCRIPTS

echo "System $loop now runing $loop2 at $MY_DATE" | tee -a $LOGFILE

首先定义了两个变量 APPS和SCRIPTS,MY_DATE这个里面的命令是格式化时间的,格式化时间都是这样写的

date +%H:%M 小时在前,然后一个分号,分钟在后。

date +%Y-%m-%d 第一个是年,然后一个-然后月,然后-然后是日。因为loop在前面,所以循环的时候,会

先拿loop里面的第一个列表内容匹配loop2列表里的1,2,3.然后是loop里的第二个内容匹配loop2的1,2

,3一直到两个里面都匹配完,循环结束。运行结果

[root@localhost Shell]# sh for_for_loop.sh

System /usr/local/mysql now runing report.sh at 17:45 on 2011-08-11

System /usr/local/mysql now runing cleanup.sh at 17:45 on 2011-08-11

System /usr/local/mysql now runing forloop.sh at 17:45 on 2011-08-11

System /usr/local/apache2 now runing report.sh at 17:45 on 2011-08-11

System /usr/local/apache2 now runing cleanup.sh at 17:45 on 2011-08-11

System /usr/local/apache2 now runing forloop.sh at 17:45 on 2011-08-11

System /usr/local/php5 now runing report.sh at 17:45 on 2011-08-11

System /usr/local/php5 now runing cleanup.sh at 17:45 on 2011-08-11

System /usr/local/php5 now runing forloop.sh at 17:45 on 2011-08-11

=========================================================================

======= UNTIL循环 =======

until循环执行一系列命令,直到条件为真是停止。until循环与while循环在处理方式上刚好相反。

一般while循环优于until循环,但在某些时候,也只是极少情况下,until循环更加有用。

until循环格式为

========================

until 条件

命令1

.....

条件可为任意测试条件,测试发生在循环末尾,因些循环至少执行一次(循环至少执行一次,注意。)

简单until循环 这段脚本不断的搜寻who命令中用户root,变量IS-ROOT保存grep命令结果。

如果找到了root,循环结束,并向用户admin发送邮件,通知他用户root已经登录,注意这里sleep命令

,它经常用于until循环中,因为必须让循环休内的命令睡眠几秒种再执行,否则会消消耗大量系统资源

#ScriptName until_who

IS_ROOT=`who | grep root`

until [ "$IS_ROOT" ]

sleep 5

echo "Watch it . roots in " | mail admin

执行结果:

To: [email protected]

Watch it . roots in

使用until循环监视磁盘空间

until循环做监视条件也很有用。假定要监视文件系统容量。当它达到一定百分比时通知管理员

下面的脚本监视文件系统/logs,不断从变量$LOOK_OUT中抽取信息,如果容量达到了90%,触发命令部分

向超级用户发送邮件,脚本退出

===========================================================

#until_mon

LOOK_OUT=`df | grep /logs | awk '{print $5}' | sed 's/%//g'`

echo $LOOK_OUT

until [ "$LOOK_OUT" -gt "90" ]

do

echo "Filesystem..logs is nearly full" | mail root

exit0

===== while循环 ======

while循环用于不断执行一系列命令,也用于从输入文件中读取数据,其格式为:

====================================

while 命令

命令2

......

虽然通常只使用一个命令,但在while和do之间,可以放几个命令。命令通常用作测试条件

只有当命令的退出状态为0时,do和done之间命令才被执行,如果退出状态不是0,则循环终止

命令执行完毕,控制返回循环顶部,从头开始直至测试条件为假。

简单while循环

#ScriptName whilecount

COUNTER=0

while [ $COUNTER -lt 5 ]

COUNTER=`expr $COUNTER + 1`

echo $COUNTER

首先定义COUNTER的值为0,然后进入while循环,while后面是一个判断,判断COUNTER的值是不是

小于等于5,第一次的时候是0,所以条件成立,进入到while循环,然后对COUNTER进行计算,在当前

值的基础上加1,然后用echo输出值,第一次0+1是1,所以WHILE会接着判断,还是小于5,接着循环。

一直到值为5,条件不成立,退出循环。那么,现在执行的结果就很明显了

[root@localhost Shell]# sh whilecount.sh

#ScriptName whileread

echo "Type <CTRL-D> to terminate"

echo -n "Enter your most liked film : "

while read FILM

echo "Yeah,great film the $FILM"

一直不停的读用户的输入,然后输入Yeah,great film the (用户输入的名字)

直到用户按CTRL+D,脚本结束。

#####################################

#Whileread2

while read ONE

echo $ONE

done < names.txt

#######################

循环读变量ONE,然后输出变量ONE,变量的来源由names.txt文件来传递。其实就是打印names.txt文件的

内容 ,跟使用命令cat naes.txt得到的结果一样

[root@localhost Shell]# cat names.txt

Louise Conrad:Accounts:ACC8987

Peter James:Payroll:PR489

Fred Terms:Customer:CUS012

James Lenod:Accounts:ACC887

Frank Pavely:Payroll:PR489

###

[root@localhost Shell]# sh whileread2.sh

============

使用IFS读文件

输出时要去除冒号域分隔符,可以使用变量IFS。在改变它之前保存IFS的当前设置,然后在脚本

执行完后恢复此设置,使用IFS可以将域分隔符改为冒号而不是空格或tab键。这里有3个域需要

加域分隔,即NAME、DEPT和ID。

为使输出看起来更清晰,对echo命令使用tab键将域分隔得更开一些,脚本如下:

#ScriptName whilereadifs

SAVEDIFS=$IFS

IFS=:

while read NAME DEPT ID

echo -e "$NAME\t $DEPT\t $ID"

done <names.txt

NFS=$SAVEDIFS

==================

#ScriptName whileread_file

HOLD_FILE=hold_file

NAME_MATCH="James Lenod"

INPUT_FILE=names.txt

>$HOLD_FILE

while read NAME DEPT TD

echo $NAME $DEPT $TD >>$HOLD_FILE

IF [ "$NAME" = "$NAME_MATCH" ]; then

echo "All entries up to and including $NAME_MATCH are in $HOLD_FILE"

exit 0

done < $INPUT_FILE

IFS=$SAVEDIFS

==============================================================

每次读一对记录

有时可能希望每次处理两个记录,也许可从记录中进行不同域的比较。每次读两个记录很容易

就是要在第一个while语句之后将第二个语句放在其后

[root@localhost Shell]# vi record.txt

record 1

record 2

record 3

record 4

record 5

record 6

—————————————————————

_______________________________________________

[root@localhost Shell]# vi readpair.sh

#ScriptName readpair

while read rec1

read rec2

echo "This is record one of a pair :$rec1"

echo "This is record one of a pair :$rec2"

echo "_____________________________________"

done < record.txt

[root@localhost Shell]# sh readpair.sh

This is record one of a pair :record 1

This is record one of a pair :record 2

_____________________________________

This is record one of a pair :record 3

This is record one of a pair :record 4

This is record one of a pair :record 5

This is record one of a pair :record 6

break

break命令允许跳出循环。break通常在进行一些处理后,退出循环或case语句。如果在一

个嵌入循环里,可以指定跳出的循环个数。如果在两层循环内,用break 2刚好跳出整个循环。

跳出case语句,下面例子中,脚本进入死循环直到用户输入数字大于5,要跳出这个循环

返回到shell提示符下

========================================================

#ScriptName breakout

while :

echo -n "Enter any number [1..5] :"

1|2|3|4|5) echo "Great you entered a number between 1 and 5"

*) echo "Wrong number..bye"

=========================================================

上例中,用户输入1-5之间的数字,都会被echo输出,如果输入其它,刚会到break命令

跳出循环。如果没有break,那么就一直循环,因为while没有指定条件,无论输入什么,都满足

continue

continue 命令类似于break命令,只有一点重要差别,它不会跳出循环,只是跳过这个循环步。

#ScriptName whilecontinue

INPUT_FILE=names2.txt

NAME_HOLD="Peter James"

LINE_NO=0

if [ -s $INPUT_FILE ]; then

while read NAME DEPT ID

LINE_NO=`expr $LINE_NO + 1`

if [ "$LINE_NO" -le 2 ]; then

if [ "$NAME" = "$NAME_HOLD" ]; then

echo "Now processing... $NAME $DEPT $ID"

echo "$0 : Sorry, file not found or there is not data in the file"

========================================================================

#ScriptName menu

#DATE:2011-08-12

MYDATE=`date -d today +"%Y-%m-%d %H:%M:%S"`

THIS_HOST=`hostname -s`

USER=`whoami`

#Loop forever

#Clear the screen

tput clear

cat <<MYDAY

______________________________________________________________

USER: $USER HOST: $THIS_HOST DATE: $MYDATE

1: List files in current directory

2: Use the vi editor

3: See who is on the system

H: Help screen

Q: Exit Menu

MYDAY

#Here document finished

echo -e -n "\tYour Choice [1,2,3,H,Q]>"

read CHOICE

case $CHOICE in

1) ls

2) vi

3) who

H|h)

#Use a here document for the help screen

This is the help screen, nothing here yet to help you!

Q|q) exit 0

*) echo -e "\t\007Unknown user response"

echo -e -n "\tHit the return key to continue"

read DUMMY