Chinaunix首页 | 论坛 | 博客
  • 博客访问: 138793
  • 博文数量: 20
  • 博客积分: 551
  • 博客等级: 下士
  • 技术积分: 260
  • 用 户 组: 普通用户
  • 注册时间: 2011-11-28 15:55
文章分类

全部博文(20)

文章存档

2012年(12)

2011年(8)

分类: LINUX

2012-02-10 13:20:57

接上shell强大功能实例珍藏:再次跟随我的脚步一起去感受和学习shell的强大功能;根据应用实例带动对shell的学习.

将脚本参数传入系统命令
可以向脚本传递位置参数,然后测试变量。这里,如果用户在脚本名字后键入目录名,
脚本将重设$ 1特殊变量为一更有意义的名字。即D I R E C TO RY。这里需测试目录是否为空,如
果目录为空,ls -A将返回空,然后对此返回一信息。

  1. # ifdirec.sh

  2. # assigning $1 to DIRECTORY variable

  3. DIRECTORY=$1

  4. if [ "`ls -A $DIRECTORY`" == "" ]; then

  5.         # if it's an empty string, then it's empty

  6.         echo "$DIRECTORY is indeed empty"

  7. else

  8.         # otherwise it is not

  9.         echo "$DIRECTORY is not empty"

  10. fi

也可以使用下面的脚本替代上面的例子并产生同样的结果。

 

  1. [root@localhost ~]# cat ifdirec2.sh

  2. #!/bin/sh

  3. # ifdirec2

  4. DIRECTORY=$1

  5. if [ -z "`ls -A $DIRECTORY`" ]

  6. then

  7.                 echo "$DIRECTORY is indeed empty"

  8. else

  9.                 echo "$DIRECTORY is not empty"

 

null:命令用法
到目前为止,条件测试已经讲完了t h e n和e l s e部分,有时也许使用者并不关心条件为真或
为假。
不幸的是i f语句各部分不能为空—一些语句已经可以这样做。为解决此问题, s h e l l提供
了:空命令。空命令永远为真(也正是预想的那样)。回到前面的例子,如果目录为空,可以
只在t h e n部分加入命令。

 

  1. [root@localhost ~]# cat ifdirectory.sh

  2. #!/bin/sh

  3. # ifdirectory.sh

  4. DIRECTORY=$1

  5. if [ "`ls -A $DIRECTORY`" == "" ]

  6. then

  7.                 echo "$DIRECTORY is indeed empty"

  8. else :

  9.                 # do nothing

  10. fi

  11. [root@localhost ~]# ./ifdirectory.sh testd

  12. testd is indeed empty

测试目录创建结果
现在继续讨论目录,下面的脚本接受一个参数,并用之创建目录,然后参数被传入命令
行,重设给变量D I R E C TO RY,最后测试变量是否为空。
if ["$DIRECTORY"=""]
也可以用
if[$# -lt 1]
来进行更普遍的参数测试。
如果字符串为空,返回一可用信息,脚本退出。如果目录已经存在,脚本从头至尾走一
遍,什么也没做。
创建前加入提示信息,如果键入Y或y,则创建目录,否则使用空命令表示不采取任何动作。
使用最后命令状态测试创建是否成功执行,如果失败,返回相应信息。

 

  1. [root@localhost ~]# cat ifmkdir.sh

  2. #!/bin/sh

  3. # ifmkdir.sh

  4. # parameter is passed as $1 but reassigned to DIRECTORY

  5. DIRECTORY=$1

  6. # is the string empty ??

  7. if [ "$DIRECTORY" == "" ]

  8. then

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

  10.                 exit 1

  11. fi

  12. if [ -d $DIRECTORY ]

  13. then : # do nothing

  14. else

  15.                 echo "The directory does not exist"

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

  17.                 read ANS

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

  19.                 then

  20.                                 echo "creating now"

  21.                                 # create directory and send all output to /dev/null

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

  23.                                 if [ $? != 0 ]; then

  24.                                                 echo "Errors creating the directory $DIRECTORY" >&2

  25.                                                 exit 1

  26.                                 fi

  27.                 else : # do nothing

  28.                 fi

  29. fi

  30. [root@localhost ~]# ./ifmkdir.sh dt

  31. The directory does not exist

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

  33. creating now

 

另一个拷贝实例
在另一个拷贝实例中,脚本传入两个参数(应该包含文件名),系统命令c p将$ 1拷入$ 2,
输出至/ d e v / n u l l。如果命令成功,则仍使用空命令并且不采取任何动作。
另一方面,如果失败,在脚本退出前要获知此信息。

 

  1. [root@localhost ~]# cat ifcp2.sh

  2. #!/bin/sh

  3. # ifcp2.sh

  4. if cp $1 $2 > /dev/null 2>&1

  5.                 # successful, great do nothing

  6. then :

  7. else

  8.                 # oh dear, show the user what files they were.

  9.                 echo "`basename $0`: ERROR failed to copy $1 to $2"

  10.                 exit 1

  11. fi

  12. [root@localhost ~]# ./ifcp2.sh myfile.lex myfile.lex.bak

  13. ifcp2.sh: ERROR failed to copy myfile.lex to myfile.lex.bak

  14. [root@localhost ~]# touch myfile.lex

  15. [root@localhost ~]# ./ifcp2.sh myfile.lex myfile.lex.bak

 

上面展现了脚本运行成功和脚本运行失败的情况。

下面的脚本用s o r t命令将文件a c c o u n t s . q t r分类,并输出至系统垃圾堆。没人愿意观察屏幕
上3 0 0行的分类页。成功之后不采取任何动作。如果失败,通知用户。

 

  1. [root@localhost ~]# cat ifsort.sh

  2. #!/bin/sh

  3. # ifsort

  4. if sort accounts.qtr > /dev/null

  5.                 # sorted. Great

  6. then :

  7. else

  8.                 # better let the user know

  9.                 echo "`basename $0`: Oops..errors could not sort accounts.qtr"

  10. fi

多个if语句
可能有时要嵌入i f语句。为此需注意i f和f i的相应匹配使用。

=====================================GNU/LinuxFreeBSD==================================

测试和设置环境变量
前面已经举例说明了如何测试环境变量E D I TO R是否被设置。现在如果未设置,则进一步
为其赋值,脚本如下:
  1. #!/bin/sh

  2. # ifseted.sh

  3. # is the EDITOR set?

  4. if [ -z $EDITOR ]; then

  5.         echo "Your EDITOR environment is not set"

  6.         echo "I will assum you want to use vi .. OK"

  7.         echo -n "Do you wish to change it now? [y..n] :"

  8.         read ANS



  9.         # check for an upper or lower case 'y'

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

  11.                 echo "enter you editor type :"

  12.                 read EIDTOR

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

  14.                         # if EDITOR not set and no value in variable EDITOR,

  15.                         # then set it to vi

  16.                         echo "No, editor entered, using vi as default"

  17.                         EDITOR=vi

  18.                         export EDITOR

  19.                 fi

  20.                 # got a value use it for EDITOR

  21.                 EDITOR=$EDITOR

  22.                 export EDITOR

  23.                 echo "setting $EDITOR"

  24.         fi

  25. else

  26.         # user

  27.         echo "Using vi as the default editor"

  28.         EDITOR=vi

  29.         export EDITOR

  30. fi
脚本工作方式如下:首先检查是否设置了该变量,如果已经赋值,输出信息提示使用v i作
为缺省编辑器。v i被设置为编辑器,然后脚本退出。
如果未赋值,则提示用户,询问其是否要设置该值。检验用户输入是否为大写或小写y,
输入为其他值时,脚本退出。
如果输入Y或y,再提示输入编辑类型。使用$ E D I TO R =“”测试用户是否未赋值和未点
击r e t u r n键。一种更有效的方法是使用-z $EDITO R方法,本文应用了这两种方法。如果测试
失败,返回信息到屏幕,即使用v i做缺省编辑器,因而E D I TO R赋值为v i。
如果用户输入了一个名字到变量E D I TO R,则使用它作为编辑器并马上让其起作用,即导
出变量E D I TO R。

检测最后命令状态
前面将目录名传入脚本创建了一个目录,脚本然后提示用户是否应创建目录。下面的例
子创建一个目录,并从当前目录将所有* . t x t文件拷入新目录。但是这段脚本中用最后状态命
令检测了每一个脚本是否成功执行。如果命令失败则通知用户。
  1. #!/bin/sh

  2. # ifmkdir2.sh

  3. DIR_NAME=testdirec

  4. # where are we?

  5. THRER=`pwd`

  6. # send all output to the system dustbin

  7. mkdir $DIR_NAME > /dev/null 2>&1

  8. # is it a directory ?

  9. if [ -d $DIR_NAME ]; then

  10.         # can we cd to the directory

  11.         cd $DIR_NAME

  12.         if [ $? == 0 ]; then

  13.                 # yes we can

  14.                 HERE=`pwd`

  15.                 cp $THERE/*.txt $HERE

  16.         else

  17.                 echo "Cannot cd to $DIR_NAME" >&2

  18.                 exit 1

  19.         fi

  20. else

  21.         echo "Cannnot create directory $DIR_NAME" >&2

  22.         exit 1

  23. fi
增加和检测整数值
下面的例子进行数值测试。脚本包含了一个计数集,用户将其赋予一个新值就可改变它。
脚本然后将当前值1 0 0加入一个新值。工作流程如下:
用户输入一个新值改变其值,如果键入回车键,则不改变它,打印当前值,脚本退出。
如果用户用y或Y响应新值,将提示用户输入增量。如果键入回车键,原值仍未变。键入
一个增量,首先测试是否为数字,如果是,加入计数C O U N TO R中,最后显示新值。
  1. #!/bin/sh

  2. # ifcounter.sh

  3. COUNTER=100

  4. echo "Do you wish to change the counter value currently set at $COUNTER

  5.     [y..n] :"

  6. read ANS

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

  8.         # yes user wants to change the value

  9.         echo "Enter a sensible value "

  10.         read VALUE

  11.         # simple test to see if it's numeric, add any number to VALUE,

  12.         # then check out return

  13.         # code

  14.         expr $VALUE + 10 > /dev/null 2>&1

  15.         STATUS=$?

  16.         # check return code of expr

  17.         if [ "$VALUE" == "" ] || [ "$STATUS" != "0" ]; then

  18.                 # send errors to standard error

  19.                 echo " You either entered nothing or a non-numeric " >&2

  20.                 echo " Sorry now exiting...counter stays at $COUNTER" >&2

  21.                 exit 1

  22.         fi

  23.         # if we are here, then it's a number, so add it to COUNTER

  24.         COUNTER=`expr $COUNTER + $VALUE`

  25.         echo " Counter now set to $COUNTER"

  26. else

  27.         # if we are here user just hit return instead of entering a number

  28.         # or anssered n to the change a value prompt

  29.         echo " Counter stays at $COUNTER"

  30. fi

下面是程序的运行结果:

  1. [root@localhost ~]# ./ifcounter.sh

  2. Do you wish to change the counter value currently set at 100

  3.         [y..n] :

  4. n

  5. Counter stays at 100

  6. [root@localhost ~]# ./ifcounter.sh

  7. Do you wish to change the counter value currently set at 100

  8.         [y..n] :

  9. y

  10. Enter a sensible value

  11. fdg

  12. You either entered nothing or a non-numeric

  13. Sorry now exiting...counter stays at 100

  14. [root@localhost ~]# ./ifcounter.sh

  15. Do you wish to change the counter value currently set at 100

  16.         [y..n] :

  17. y

  18. Enter a sensible value

  19. 250

  20. Counter now set to 350

=====================================GNU/LinuxFreeBSD==================================


以下是用户登录时启动应用前加入相应安全限制功能的基本框架。首先提示输入用户名
和密码,如果用户名和密码均匹配脚本中相应字符串,用户登录成功,否则用户退出。
脚本首先设置变量为假—总是假定用户输入错误, s t t y当前设置被保存,以便隐藏
p a s s w d域中字符,然后重新保存s t t y设置。
如果用户I D和密码正确(密码是easypasswd),明亮I N VA L I D U S E R和I N VA L I D PA S S W D设
置为n o表示有效用户或密码,然后执行测试,如果两个变量其中之一为y e s,缺省情况下,脚
本退出用户。
键入有效的I D和密码,用户将允许进入。这是一种登录脚本的基本框架。下面的例子中
有效用户I D为root。
提示:在实际中千万不要这么做,任何人都知道用root身份进行测试是很危险的。
  1. #!/bin/sh

  2. # ifpass.sh

  3. # set the variables to false

  4. INVALID_USER=yes

  5. INVALID_PASSWD=yes

  6. # save the current stty settings

  7. SAVEDSTTY=`stty -g`

  8. echo "You are logging into a sensitive area"

  9. echo -n "Enter your ID name :"

  10. read NAME

  11. # hide the characters typed in

  12. stty -echo

  13. echo "Enter your password :"

  14. read PASSWORD

  15. # back on again

  16. stty $SAVEDSTTY

  17. if [ "$NAME" == "root" ]; then

  18.         # if a valid then set variable

  19.         INVALID_USER=no

  20. fi

  21. if [ "$PASSWORD" == "easypasswd" ]; then

  22.         # if valid password then set variable

  23.         INVALID_PASSWD=no

  24. fi

  25. if [ "$INVALID_USER" == "yes" -o "$INVALID_PASSWD" == "yes" ]; then

  26.         echo "`basename $0 :` Sorry wrong password or userid"

  27.         exit 1

  28. fi

  29. # if we get here then their ID and password are OK.

  30. echo "correct user id an password given"
 
下面是对应两种不同情况的输出结果。
  1. [root@localhost ~]# ./ifpass.sh

  2. You are logging into a sensitive area

  3. Enter your ID name :root

  4. Enter your password :

  5. correct user id an password given

  6. [root@localhost ~]# ./ifpass.sh

  7. You are logging into a sensitive area

  8. Enter your ID name :root

  9. Enter your password :

  10. ifpass.sh Sorry wrong password or userid
elif用法
if then else语句的e l i f部分用于测试两个以上的条件。

使用elif进行多条件检测
使用一个简单的例子,测试输入脚本的用户名。脚本首先测试是否输入一个名字,如果
没有,则什么也不做。如果输入了,则用e l i f测试是否匹配r o o t、l o u i s e或d a v e,如果不匹配其
中任何一个,则打印该名字,通知用户不是r o o t、l o u i s e或d a v e。
  1. #!/bin/sh

  2. # ifelif.sh

  3. echo -n "enter your login name :"

  4. read NAME

  5. # no name entered do not carry on

  6. if [ -z $NAME ] || [ "$NAME" == "" ]; then

  7.         echo "You did not enter a name"

  8. elif

  9.         # is the name root

  10.         [ "$NAME" == "root" ]; then

  11.         echo "Hello root"

  12. elif

  13.         # or is it louise

  14.         [ $NAME == "louise" ]; then

  15.         echo "Hello louise"

  16. elif

  17.         # or is it dave

  18.         [ "$NAME" == "dave" ]; then

  19.         echo "Hello dave"

  20. else

  21.         # no it's somebody else

  22.         echo "You are not root or louise or dave but hi $NAME"

  23. fi

 

  1. 运行上述脚本,给出不同信息,得结果如下: 

 

  1. [root@localhost ~]# chmod +x ifelif.sh

  2. [root@localhost ~]# ./ifelif.sh

  3. enter your login name :dave

  4. Hello dave

  5. [root@localhost ~]# ./ifelif.sh

  6. enter your login name :

  7. You did not enter a name

  8. [root@localhost ~]# ./ifelif.sh

  9. enter your login name :Peter

  10. You are not root or louise or dave but hi Peter

多文件位置检测
假定要定位一个用户登录文件,已知此文件在/ u s r / o p t s / a u d i t / l o g s或/ u s r / l o c a l / a u d i t / l o g s中,
具体由其安装人决定。在定位此文件前,首先确保文件可读,此即脚本测试部分。如果未找
到文件或文件不可读,则返回错误信息。脚本如下:

 

  1. #!/bin/sh

  2. # ifcataudit.sh

  3. # locations of the log file

  4. LOCAT_1=/usr/opts/audit/logs/audit.log

  5. LOCAT_2=/usr/local/audit/audit.logs

  6. if [ -r $LOCAT_1 ]; then

  7.         # if it is in this directory and is readable then cat is

  8.         echo "Using LOCAT_1"

  9.         cat $LOCAT_1

  10. elif

  11.         # else it then must be in this direcotory, and is it readable

  12.         [ -r $LOCAT_2 ]

  13. then

  14.         echo "Using LOCAT_2"

  15.         cat $LOCAT_2

  16. else

  17.         # not in any of the directories...

  18.         echo "`basename $0`: Sorry the audit file is not readable or cannot be

  19.         localted." >&2

  20.         exit 1

  21. fi

运行上面脚本,如果文件在上述两个目录之一中并且可读,将可以找到它。如果不是,
返回错误并退出,下面结果失败,因为假想的文件并不存在

  1. [root@localhost ~]# ./ifcataudit.sh

  2. ifcataudit.sh: Sorry the audit file is not readable or cannot be

  3.                 localted.

到了此处又得告一段落了,精彩过后就是回味无穷;这些只得深思和深入的研究慢慢学知识的海洋中要学的东西很多但不可能短时间内学完;人生就是在一天天的学习一天天的成长,该上班了就先写这么多吧

阅读(2023) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~