Linux----shell 编程(脚本)

目录

1为什么学习脚本

2脚本的执行

在撰写脚本时,最好养成如下良好的习惯:

​​​​​​​3卷标与运算符declare

4交互式脚本

​​​​​​​5脚本逻辑判断式与表达式

1)逻辑判断式

2)运算符

​​​​​​​6条件判断

1)if…then…fi

2)case…esac

​​​​​​​7循环

(1)使用while:

(2)使用until:

​​​​​​​8如何调试脚本


​​​​​​​1为什么学习脚本

可以更加了解与控制Linux,使Linux动作更顺畅,而且可以高枕无忧地让你的Linux服务器在Internet上提供相关服务的话,那么应该把脚本学习好。

除了针对主机,脚本还有相当多的功能,例如计算,可以不必用编程语言来写,脚本本身是个可以使用的程序。例如:防火墙连续规则(iptables),启动加载程序项(/etc/rc.d/rc.local),均是脚本。

​​​​​​​2脚本的执行

上一个实验中学习了一堆变量、管线指令等,都是为了给脚本做铺垫。将我们要执行的内容写成一个脚本,让系统依据这个脚本来执行我们想要的东西。基本上,执行脚本时,bash判断的步骤为:

1)如果读取到个Enter符号(CR),就尝试开始执行该命令;

2)如同前面bash  command提到的,指令间的多个空白会被忽略;

3)空白行也将被忽略,并且Tab也不会被理会;

4)如果一行内容太多,则可以使用\延伸至下一行;

5)此外,使用最多的#可做为注释。任何加在#后面的字,将全部被视为注释文字而被忽略。

在撰写脚本时,最好养成如下良好的习惯:

1)先声明使用的shell为何(特别留意这一点,在某些情况下,例如/etc/crontab,如果没有声明使用的shell,常会出现错误信息而导致脚本无法被执行)。

2)注明该脚本的内容功能、版本信息、作者、文件创建日期等。

3)每一个大步骤的主要功能(也顺便供自己未来做修改之用)。

那么,如何执行脚本文件?执行的方法有两种:

                1. 一个是将文件改成可以执行的属性,如chmod  755  scripts.file,然后执行该文件;
                2. 另一种则是直接以sh这个执行文件来执行脚本内容,如sh  scripts.file。

举例1:一个简单的脚本:在屏幕上显示Hello !How are you?,可以这样写(注:最常用来作为shell scripts的编写软件就是vi,有空要多熟悉vi):

# mkdir  test; cd  test                         //建立一个新的目录,所有的脚本都暂存在此!

# vi  test01-hello.sh                     //为了醒目,脚本的文件扩展名为sh

#!/bin/bash                                    //在#之后加上!与shell的名称,用来声明使用的shell

#这个脚本的用途在屏幕上显示Hello ! How are you

#创建日期:2007-4-9

#Written  by  xag

hello=Hello\\!\How\are\you\\?        //这是定义变量,其中代表一个空格字符,由于Hello与!之间有空格,而这是一个整体字符串赋值所以使用\将这些字符连接起来赋值给变量hello

echo $hello

#sh  test01-hello.sh                             //用sh来执行脚本

Hello ! How are you ?                            //输出结果

说明:黑色底纹部分为在vi里编辑的内容,汉字若输出不了,则可以使用英文来代替

这里注意:

  1. 所有在脚本里的东西,基本规则(如变量设定规则)需要与在命令行下相同;
  2. 脚本的后缀名最好为sh,以方便他人识别;
  3. 并非加上.sh就是可执行文件,还需要查看属性中是否有x属性

举例2:稍微复杂一点的脚本,若一个脚本里有两个以上的变量要相互引用,该如何做?

# vi  test02-2var.sh

#!/bin/bash

#这个脚本用于引用两个变量,顺便比较一下"'的异同

#Date:2007-4-9

#Written by xag

name="xag"

myname1="My  name  is  $name"

myname2='My  name  is  $name'

echo  $name

echo  $myname1

echo  $myname2

#sh  test02-2var.sh

xag

My  name  is  xag

My  name  is  $name

从这里可以看出,"与'最大的不同就在于能不能保存变量内容。再提醒一次,单引号“'”里的数据都将变成单纯的字符,而不是有特殊字体.

​​​​​​​3卷标与运算符declare

变量的声明,不声明类型直接参与运算所得结果分析:

# a=3

# b=5

# c=$a*$b

# echo  $c

3*5                      //显示结果为什么不是15?怎么变成了字符串?

这是我们没有定义该变量,则该变量默认是呈现字符串的形式,自然$c变成为字符串形式了。故变量使用前应进行声明,用declare进行声明。

declare

格式:declare  [-afirx]                            //参数说明:-a定义为数组array;-f定义为function;-i定义为整数integer;-r定义为只读;-x定义为通过环境输出变量

范例:

#declare  -i  a=3

#declare  -i  b=5

#declare  -i  c=$a*$b

#echo  $c

//显示结果

4交互式脚本

最简单的交互式指令是read指令,read的功能就是将你在键盘上输入的内容放到变量中,如:

# read  name

xag                                                    //这里直接在键盘上输入数据

# echo  $name

xag                                                    //显示结果

例如:将你在键盘输入的数据显示出来

# vi  test03-read.sh

#!/bin/bash

#This program is used to "read" variables

#xag 2007-4-9

echo  "Please keyin your name, and press Enter to start."

read  name

echo  "This is your keyin data: $name"

#sh  test03-read.sh

Please keyin your name, and press Enter to start.

xag

下面讲解如何定义脚本的参数代号?

格式:myscripts  opt1  opt2  opt3   opt4   opt5   opt6  opt7   opt8   opt9

        $0      $1    $2    $3    $4     $5     $6   $7     $8    $9

上面的意思是说,在这个脚本(myscripts)中,只要用变量名称为$0,就表示myscripts,即:

  1. $0:myscripts,亦即脚本的文件名(像C中的main参数中的argv[0])
  2. $1:opt1,亦即第一个附加的参数
  3. $2:opt2,亦即第二个附加的参数
  4. $3:opt3,亦即第三个附加的参数
  5. ……

下面通过一个具体的例子说明:

# vi test04-0123

#!/bin/bash

#This program will define what is the parameters

#xag 2007-4-9

echo "This script's name: $0"

echo "parameters  $1  $2  $3"

# sh  test04-0123  pa1  pa2  pa3

This scipt's name: test04-0123

paramters  pa1  pa2  pa3

这个参数用法在运用上很重要,例如当你要取得脚本的名称时(因为有时候用户会自行更改文件名称),这个功能变量就相当重要了。

​​​​​​​5脚本逻辑判断式与表达式

1)逻辑判断式

几个重要的概念

逻辑卷标

含义

1.

关于文件与目录的逻辑卷标

-f

常用!检测文件是否存在

-d

常用!检测目录是否存在

-b

检测是否为一个block文件

-c

检测是否为一个character文件

-S

检测是否为一个socket标签文件

-L

检测是否为一个符号连接文件

-e

检测某个东西是否存在!可以是任何东西

2.

关于程序的逻辑卷标

-G

检测是否由GID所执行的程序拥有

-O

检测是否由UID所执行的程序拥有

-P

检测是否为程序间传送信息的name pipe或FIFO

3.

关于文件的属性检测

-r

检测是否为可读属性

-w

检测是否为可写入属性

-x

检测是否为可执行属性

-s

检测是否为非空白文件

-u

检测是否为具有SUID属性

-g

检测是否为具有SGID属性

-k

检测是否具有sticky bit属性

4.

两个文件之间的判断与比较。例如test file1 –nt file2

-nt

第一个文件比第二个文件新

-ot

第一个文件比第二个文件旧

-ef

第一个文件与第二个文件为同一个文件(诸如链接文件)

5.

逻辑与(and)和或(or)

&&

逻辑与

||

逻辑或

2)运算符

bash shell scripts的运算符的加减乘除运算

运算符

含义

=

等于

!=

不等于

<

小于

>

大于

-eq

等于

-ne

不等于

-lt

小于

-gt

大于

-le

小于或等于

-ge

大于或等于

-a

双方都成立(and)

-o

单方成立(or)

-z

空字符

-n

非空字符

逻辑判断式与if…then…fi的关系密不可分,后面讲解判断式中最常用的语法。

​​​​​​​6条件判断

1)if…then…fi

语法格式:if  [ 条件判断一 ]  &&  (||)  [ 条件判断二 ];  then  //if是起始,后面可以接若干个判断式,使用&&或||执行判断

          elif  [ 条件判断三 ]  &&  (||)  [ 条件判断四 ];  then //第二段判断,如果第一段不符合要求就转到此搜寻条件,执行第二段程序

          else                                                                                        //当前两段都不符合时,就执行这段内容

          fi                                                                                            //结束if  then的条件判断

说明:

① 在[]中,只能有一个判断式;

② 在[]与[]之间,可以使用&&或||结合判断式;

③ 每一个独立的组件之间需要用空格键隔开。(这一点最容易犯错误,如[后有一空格,]前有一空格)

例:# vi  test05-ifthen.sh

#!/bin/bash

#This program is used to study if then

#xag  2007-4-10

echo  "Press  y  to  continue"

read  yn

if  [ "$yn" = "y" ];then

   echo  "script  is  running…"

else

   echo  "STOP!"

fi

# sh  test05-ifthen.sh

Press  y  to  continue

y                                       //你输入的内容

script  is  running…

# sh  test05-ifthen.sh

Press  y  to  continue

n                                       //你输入的内容,注意这里=两边也应有空格

STOP!

程序的意思是输入y继续执行,否则停止。这里有个问题,如果输入的是Y,程序还是停止了,怎么办?这个时候需要用到||。程序如下:

# cp  test05-ifthen.sh  test06-ifthen.sh

# vi  test06-ifthen.sh                                      //在原来基础上修改

#!/bin/bash

#This program is used to study if then

#xag  2007-4-10

echo  "Press  y  to  continue"

read  yn

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

   echo  "script  is  running…"

else

   echo  "STOP!"

fi

此时程序执行时,输入y或Y程序都会继续执行。

例:脚本运行时必需带参数

# vi  test07-ifthen.sh

#!/bin/bash

#set parameters in the if then

#需要加上hello这个参数才会正确显示

#xag 2007-4-11

if  [  "$1" = "hello"  ];  then

    echo "Hello! How are you?"

elif  [  "$1" = ""  ]; then

    echo "You MUST input parameters"

else

    echo "The only accept parameter is hello"

fi

2)case…esac

语法格式:case  种类方式(string)  in

种类方式一)

   程序执行段

   ;;                                //种类方式一的结束符号

种类方式二)

   程序执行段

   ;;                               

*)

   echo  "Usage: { 种类方式一 | 种类方式二 }"    //列出可以利用的参数值

   exit  1

   esac                                              //case的结束处

种类方式(string)的格式主要有两种:

  1. 直接输入:就是以“执行文件 + string”的方式执行(/etc/rc.d/init.d里的基本设定方式),string可以直接写成$1(在执行文件后直接加入第一个参数)
  2. 交互式:就是由屏幕输出可能的项,然后让用户输入,通常必须配合read variable,然后string写成$variable的格式。

举例:建立一个名为test08-case.sh的文件做个试验。假如共有3个选项,分别为one,two,three,并假设使用直接输入方式,则可以写成:

# vi test08-case.sh

#!/bin/bash

#program: Using  case  mode

#xag  2007-4-11

#content: I will use this program to study the case mode!

#1.pring this program

 echo  "This program will print your selection!"

 case  $1 in

  one)

echo "your choice is one"

;;

 two)

     echo "your choice is two"

     ;;

 three)

     echo "your choice is three"

     ;;

 *)

    echo "Usage {one|two|three}"   //列出可以使用的参数(如果用户输入错误的参数)

    exit  1

esac

# sh  test08-case.sh            //执行结果显示没有相对应的参数

This program will print your selection!

Usage {one|two|three}

# sh  test08-case.sh  three

This program will print your selection!

Your choice is three

再看交互式的case的用法,对上面的例子做个修改

# vi test09-case.sh

#!/bin/bash

#program: Using  case  mode

#xag  2007-4-11

#content: I will use this program to study the case mode!

#1.pring this program

 echo  "Press your select  one ,two ,three"

 read number

 case  $number  in

  one)

echo "your choice is one"

;;

 two)

     echo "your choice is two"

     ;;

 three)

     echo "your choice is three"

     ;;

 *)

    echo "Usage {one|two|three}"   //列出可以使用的参数(如果用户输入错误的参数)

    exit  1

esac

# sh  test09-case.sh  

Press your select  one ,two ,three

Two                                                 //这一行是你输入的内容

your choice is two

​​​​​​​7循环

最简单的循环语句如下:

    1. for((条件1;条件2;条件3))
    2. for variable in variable1 variable2……
    3. while [ condition1 ] && {||} [ condition2 ]…
    4. until [ condition1 ] && {||} [ condition2 ]…

for 是已经知道要运行几次,至于until与while则分别是:

    1. until:直到条件符合的时候才退出程序;
    2. while:当条件符合时,就继续做。

举例1:利用for计算1+2+3+…+100,用脚本如何写?有很多方式,我们来谈谈do…done。

#vi test10-loop.sh

#!/bin/bash

#Using for and loop

#xag 2007-4-12

declare –i s                      #变量声明

for  ( ( i=1;i<=100;i=i+1))

do

  s=s+i

done

echo "The count is :$s"

# sh test10-loop.sh

The count is :5050

请注意,for((条件1;条件2;条件3))是必要的。

    1. 条件1:可以看成是初始值,如例子中,初始值是i=1。
    2. 条件2:可以看成是终止值,如例子中,当i<=100时就给出程序停止运行的条件。
    3. 条件3:可以看成是步长,也就是说,i每次加1。

上面的例子是说:由i=1开始到i=100,每次i都加1来执行下面的程序段(就是s=s+i),当i>100(也就是i=101),就跳出这段程序。

举例2:使用while或until来实现上例。

(1)使用while:

# vi test11-loop.sh

#!/bin/bash

#Using while and loop

#xag 2007-4-12

declare  –i  i

declare  –i  s

while [ "$i" != "101" ]

do

   s=s+i

   i=i+1

done

echo "The count is:$s"

(2)使用until:

# vi test12-loop.sh

#!/bin/bash

#Using until and loop

#xag 2007-4-12

declare  –i  i

declare  -i  s

until  [ "$i" = "101" ]

do

  s=s+i

  i=i+1

done

echo "The count is:$s"

# sh  test11-loop.sh   //若出错请使用bash  test11-loop.sh

The count is:5050

举例3:下面的例子是另外一种循环方式,可以用来判断非数字类型。

# vi  test13-for.sh

#!/bin/bash

#Using for … do …done

#xag 2007-4-12

LIST="Tomy  Jony  Mary  Geoge"

for  i  in  $LIST

do

echo  $i

done

# sh  test13-for.sh

Tomy

Jony

Mary

Geoge

这种格式是以空格键分开i变量的各选择项,也就是说,上面的$LIST变量中,以空格键分隔共可以分离出4个项,所以,使用do…done就可以分别输出这4个项。那么,有没有办法利用这个特性将Linux主机帐号显示出来?很简单,利用cut跟sort及/etc/passwd文件来完成这个脚本,如下:

# vi test14-for.sh

#!/bin/bash

#Using for and loop to read the account of this linux server!

#xag 2007-4-12

account=`cut –d ":" –f1 /etc/passwd |sort `

echo "The following is linux server's account"

for  i  in  $account

do

  echo $i

done

# sh  test14-for.sh

The following is linux server's account

adm

aerosol

alenchan

amanda

apache

……

举例4:接下来我们以交互式实现循环功能,即当我们输入y或Y时,程序就结束。可以这样做:

# vi test15-loop.sh

#!/bin/bash

#Using until

#xag 2007-4-12

echo "Press Y/y to stop"

until [ "$yn" = "y" ] || [ "$yn" = "Y" ]

do

  read yn

done

echo "Stop here"

# sh  test15-loop.sh

Press Y/y to stop                                                //下面的几行除了Stop here之外,都是你自己随意输入的内容:

GDSG

A

Y

Stop here

上面说的是,当输入Y或y时才跳出do…done循环,而去执行下面的东西。

举例5:接下来,我们来判断目录是否存在,这是常用的。看看所谓的逻辑判断式的使用方法。可以使用条件判断来断定到底有没有文件(用-e)或者该名称是属于目录还是文件(-d,-f),接下来我们判断一个流程:

    1. 先查看~/test/logical这个名称是否存在;
    2. 若不存在,则使用touch建立一个文件,建立完成后退出;
    3. 如果存在,判断该名称是否为文件,若为文件则将之删除后建立一个目录,文件名为logical,之后退出;
    4. 如果存在,而且该名称为目录,则移除此目录。

看起来似乎很复杂,其实很简单。如下:

# vi test16-ifthen.sh

#!/bin/bash

#Using if and then to select file or directory

#xag 2007-4-12

if  [ ! –e logical  ];then

   touch logical

   echo "Just make a file logical"

elif  [  -e  logical  ] &&  [  -f  logical  ];then

   rm  logical

   mkdir  logical

   echo  "remove file:logical"

   echo  "and make directory logical"

   exit  1

elif  [  -e  logical  ]  &&  [  -d  logical  ];then

   rm  -rf  logical

   echo  "remove directory:logical"

else

   echo "Does here have anything?"

fi

然后请你依次执行sh  test16-ifthen.sh ; ll 看看这个目录下logical文件有什么变化。这个动作可以让我们很轻松地判别出某个文件是否存在。

​​​​​​​8如何调试脚本

脚本在执行之前,最怕的就是出现问题,那么如何调试脚本?有没有办法不需要直接执行该脚本就可以判断是否有问题?当然有,我们就直接以sh进行判断。

sh语法格式:sh  [-nvx] scripts

-n:不执行脚本,查询脚本内的语法,若有错误则列出

-v:在执行脚本之前,先将脚本的内容显示在屏幕上;

-x:将用到的脚本内容显示在屏幕上,与-v稍微不同。

如:

# sh  -n  test01-hello.sh

# sh  -v  test01-hello.sh

#!/bin/bash

#这个脚本的用途在屏幕上显示Hello ! How are you

#创建日期:2007-4-10

#Written  by  xag

hello=Hello\\!\How\are\you\\?

echo $hello

Hello ! How are you

# sh  –x  test01-hello.sh

+ hello=Hello ! How are you

+ echo  'Hello !' How are you

Hello ! How are you

熟悉sh的用法,可以使你在管理Linux的过程中得心应手。

对于Shell Scripts的学习方法,需要多看、多模仿,并将其修改为已用,这是最快的学习手段。网上有很多人在开发一些很有用的脚本,可以将对方的脚本拿来,并且改成适合自己主机的脚本,那么学习效果会更好。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值