9.Linux的程序化脚本(Shell Scripts)


目录

1.什么是 Shell scripts?

2.执行shell scripts的一些规则

3.编写简单的script

4.数值运算:简单的加减乘除

5.善用判断式 

重点:$?(指令返回值),&& 或 || 

5.1.利用 test 指令的测试功能

6.条件判断式

6.1.利用 if .... then

6.2.利用 case ..... esac 判断

6.3.利用 function 功能 

6.3.循环 (loop)

6.3.1.while do done, until do done (不定循环)

6.3.2.for...do...done (固定循环)

6.3.3.for...do...done 的数值处理


 


1.什么是 Shell scripts?

是利用 shell 的功能所写的一个『程序 (program)』,这个程序是使用纯文本文件,将一些 shell 的语法与指令(含外部指令)写在里面, 搭配正规表示法、管线命令与数据流重导向等功能,以达到我们所想要的处理目的,简单的说, shell script 就像是早期 DOS 年代的批处理文件 (.bat) ,最简单的功能就是将诸多指令汇整写在一起, 使使用者很轻易的就能够一个按键的方法去处理复杂的动作 (执行一个档案"shell script" ,就能够一次执行多个指令),shell script 可以简单的被看成是批处理文件, 也可以被说成是一个程序语言,且这个程序语言由于都是利用 shell 与相关工具指令, 所以不需要编译即可执行,且拥有不错的排错 (debug) 工具,以,他可以帮助系统管理员快速的管理好主机。

2.执行shell scripts的一些规则

1. 指令的执行是从上而下、从左而右的分析与执行;
2.  指令、选项与参数间的多个空白都会被忽略掉;
3. 空白行也将被忽略掉,而且 [tab] 按键所推开的空白同样视为空格键;
4. 如果读取到一个 Enter 符号 (CR) ,就尝试开始执行该行 (或该串) 命令;
5. 如果如果一行的内容太多,则可以使用『 \[Enter] 』来延伸至下一行;
6. 『 # 』可做为批注!任何加在 # 后面的资料将全部被规为批注文字而被忽略,不会作为程序运行!

  • 如何去执行一个脚本程序

假如在/home/test目录下,有一个脚本程序bash.sh,如何执行呢?

o  绝对路径:使用 /home/test/bash.sh 来下达指令;
o  相对路径:假设工作目录在 /home/test/ ,则使用 ./bash.sh 来执行
o  变量『PATH』功能:将 shell.sh 放在 PATH 指定的目录内,例如: ~/test/

3.编写简单的script

注意事项:

1.第一行 #!/bin/bash 在宣告这个 script 使用的 shell 名称,系统才知道是用哪个shell去解析这些命令,而这里指定的是bash.

2.除了第一行,其他如果开头以#开头,都是代表注释。

3.良好的写程序习惯能提高你的工作效率,比如一个脚本除了程序应该还有其他的命令,比如:1. 内容与不功能; 2. 版本信息; 3. 作者不联绚方式; 4. 建檔日期;5. 历史纪录 等等。

例子:

写一个简单的脚本,显示第一部分显示日期,第二部分显示日历,那么需要用到两个命令,那就是date,和cal。

在、/test下新建一个档案,命令为shell01.sh,使用vim编辑器编辑如下:

编辑内容如下:

写好脚本后退出,可以看一下,shell01.sh的权限:

给这个档案加上可执行权限:使用命令:chmod +x shell01.sh

通过上面知道,我们可以有三个方法去执行这个脚本:

第一种:使用相对路径,直接在工作目录下执行

使用命令:./shell01.sh

第二种:使工作目录回到家目录,需要使用绝对路径。

使用命令:~/test/shell01.sh

第三种:修改环境变量PATH,把路径:~/test/ 加到环境变量上

无论在哪个工作目录下,现在直接使用命令:shell01.sh


4.数值运算:简单的加减乘除

我们可以使用declare来定义变量的类型, 当变量定义成为整数后才能进行加减运算啊!此外,我们也可以利用『 $((计算式)) 』来进行数值运算。

例子1:使用declare把变量定义成整形进行加法的运算:

例子2:直接使用let进行数值运算:

可以使用"(())"这样两对括号代替let进行数值运算:


5.善用判断式 

重点:$?(指令返回值),&& 或 || 

  • $?:就像一个容器一样,传回执行指令是否正确的结果,它只会记录上一次命令执行的结果,如果上一次执行的结果是正确的话此值就是:0,如果上一次执行结果是错的话就是:非0

例子:

执行命令:cal,肯定是正确的结果,返回0,再次执行:aaa,错误,返回0:。

  •  && 或 ||

这两个符号也可以和多条命令结合一起执行,用&& 或者 || 符号分开,但是他们的含义不一样。如下表所示:

注释:cmd1代表一条指令,cmd2代表另一条指令

指令说明
cmd1 && cmd2

1.如果cmd1执行的结果是正确的,则执行cmd2

2.如果cmd1执行结果是错误的,则不执行cmd2

注释:其实就是判断 cmd1和cmd2与的结果是否正确,如果第一个错了的话,与的结果肯定为错,没必要执行第二个了。

cmd1  || cmd2

1.如果cmd1执行结果是正确的,则不执行cmd2

2.如果cmd1执行结果是错误的,则执行cmd2

注释:两个数值进行或运算,只要有一个是正确的结果就是正确,如果第一个正确就没有必要去验证后面那个了,原理一样。

例子1:

使用命令: cal && echo OK 

解释:命令1是正确的,那就执行命令2

例子2:

使用命令:aaaa && echo OK

提示: || 符号的逻辑是一样的。


5.1.利用 test 指令的测试功能

  • 关于某个档名的『文件类型』判断,如 test -e filename 表示存在否
测试标志含义
-e该“档名”是否存在?
-f该“档名”是否在且为档案(file)?
-d该“文件名”是否寻在且为目录(directory)?
-b该“档名”是否寻在且为一个block device装置?
-c该“档名”是否存在且为一个character devicce 设备?
-S该“档名”是否存在且为一个Socket档案?
-p该“档名”是否存在且为一个FIFO(pipe)档案?
-L该“档名”是否存在且为一个链接档案?
  •  关于档案的权限侦测,如 test -r filename 表示可读否 (但 root 权限常有例外)
测试标志含义
-r侦测该档名是否存在且具有“可读”的权限?
-w侦测该档名是否存在且具有“可写”的权限?
-x侦测该档名是否存在且具有“可执行”的权限?
-u侦测该档名是否存在且具有“SUID”的属性?
-g侦测该档名是否存在且具有“SGID”的属性?
-k侦测该档名是否存在且具有“Sticky bit”的属性?
-s侦测该档名是否存在且具为“非空白档案”?
  • 两个档案之间的比较,如: test file1 -nt file2
测试标志含义
-nt(newer than)判断file1是否比file2新
-ot(older than)判断file1是否比file2旧
-ef判断file1 与 file2 是否为同一个档案,可用在判断hard link 的判定上,主要意义在判断,两个档案是否均指向同一个inode.
  • 关于两个整数之间的判定,例如 test n1 -eq n2
测试标志含义
-eq两数值相等(equal)
-ne两数值不等(not equal)
-gtn1 大于n2(greater than)
-ltn1 小于 n2 (less than)
-gen1 大于等于 n2(greater than or equal)
-len1 小于等于n2(less than or equal)
  • 判定字符串的数据
测试标志含义
test -z string判定字符串是否为0?若string为空字符串,则为true
test -n string

判定字符串是否为非0?若string为空字符串,则为false

注意:-n 可以省略

test  str1  = str2判定str1是否等于str2,若相等,则传回 true
test str1  != str2判定str1 是否不等于str2,若相等,则传回false
  • 多重条件判定,例如:test -r filename -a -x filename
测试标志含义
-a(and)两种状况同时成立,例如:test -r file -x file ,则file同时具有r与x权限时,才回传true
-o(or)两状态任何一个成立,例如:test -r file -o -x file ,则file具有r或者x权限时,就会传回true
!相反状态,如:test! -x file ,当file不具有x时,返回ture

例子1:

创建两个变量,然后判断两个变量的值是否相等

例子2:利用中括号“[ ]”代替test


6.条件判断式

6.1.利用 if .... then

语法:

if [ 条件判断式 ]; then
            当条件判断式成立时,可以进行的指令工作内容;

elif [ 条件判断式 ]; then
            当条件判断式成立时,可以进行的指令工作内容;

elif [ 条件判断式 ]; then

           当条件判断式成立时,可以进行的指令工作内容;

                  .

                  .

 else
           当条件判断式成立时,可以进行的指令工作内容;
fi      <==将 if 反过来写,结束 if 的意思!

例子1:

我们知道、/etc下的passwd档案存放在我们的用户密码等信息,而且第一项开始就是用户名,如果我们想测试一个用户是否存在的话可以通过查看这个用户名是否存在来判定,通过位置变量传递一个参数,然后通过grep提取开头有我们所输入用户名的行,那么这个用户就存在,否则不存在这个用户。

新建一个脚本文件,命名为:sh02.sh

运行脚本:

提示:如果不想显示提取出来的结果,给grep加上一个-q选项。

例子2:

让用户输入一个年龄,然后根据年龄判定现在所处的阶段,比如小孩,年轻人...

新建一个脚本程序,命名为:sh03.sh

代码如下:

#!/bin/bash
read -p "Please enter your age: " name
if [ "$name" -le 0 ] || [ "$name" -ge 150 ]; then
        echo "Sorry,Please enter a correct age!"
elif [ "$name"  -gt 0 ] && [ "$name" -le 20 ]; then
        echo "hello,kids!"
elif [ "$name"  -gt 20 ] && [ "$name" -le 50 ]; then
        echo "hello,adults!"
else
        echo "hello,senior citizens!"
fi

运行这个脚本程序:

技巧:在脚本中加入set命令进行排错。


6.2.利用 case ..... esac 判断

语法:

case  $变量名称 in                                 <==关键词为 case ,注意变量前的$符号
        "第一个变量内容")                          <==每个变量内容建议用双引号括起来,关键词则为小括号 )
                    程序段
                     ;;                                        <==每个类删结尾使用两个连续的分号来处理!
         "第二个变量内容")
                    程序段
                     ;;
*)                                                              <==最后一个变量内容都会用 * 来代表所有其他值不包括第一个变量内容与第二个                                                                         变量内容的其他程序执行段。
                   exit 1
                   ;;

esac
                                                          <==最终的 case 结尾。

 

例子1:

使用位置变量输入一个值,然后通过case判断这个字符串,然后输出相对应结果:

新建一个脚本,命名为:sh04.sh

代码如下:

#!/bin/bash
case $1 in
        [Aa]lice)
                echo "my name is Alice!"
                ;;
        bob)
                echo "my name is bob"
                ;;
        tom)    echo "my name is tom"
                ;;
        *)
                echo "i don't know who i am!"
esac

运行脚本:

例子2:

新建一个脚本,然后根据输入的数字来显示名字:

命名为:sh05.sh

代码如下:

#!/bin/bash
cat <<END
        1) Alice
        2) tom
        3) bob
        4) Jude
END
read -p "Please enter a number: " num
case $num in
        1)
                echo Alice
                ;;
        2)
                echo tom
                ;;
        3)      echo bob
                ;;
        4)      echo Jude
                ;;
        *)
                echo "!!!!error!!!!"
esac

运行脚本:

6.3.利用 function 功能 

功能:简单的说,其实, 函数可以在 shell script 当中做出一个类似自定义执行指令的东西,最大的功能是, 可以简化我们很多的程序代码,使用函数帮我们把重复执行的使用一个函数的功能打包起来,然后需要使用的时候,只需要调用这个函数就可以了。

语法:

function 函数名() {
            程序段
}

提示:function也可以省略。

例子:

新建一个脚本,命名为:sh06.sh

代码如下:

#!/bin/bash
function test(){
        echo this is a test function.
        echo hello world!

}
echo "*************first test ****************"
test
echo "*************second test ***************"
test

运行脚本:


6.3.循环 (loop)

6.3.1.while do done, until do done (不定循环)

语法:

while [ condition ]                     <==中括号内的状态就是判断式
do                                             <==do 是循环的开始!
            程序段落
done                                         <==done 是循环的结束

注意:while 的中文是『当....时』,所以,这种方式说的是『当 condition 条件成立时,就进行循环,直到condition 的条件不成立才停止』的意思。

语法:

until [ condition ]
do
             程序段落
done

注意:和while相反,当condition条件成立时,就结束执行,否则一直执行。

例子1:

新建一个脚本文件,命名为:sh07.sh,定义一个变量sum等于,当sum小于0的话,就开始循环自增,直到sum的值大于或者等于10,才停止自增。

#!/bin/bash
sum=0
while [ "$sum" -lt 10 ]
do
        let sum+=1
        echo $sum
done  

运行脚本:

例子2:

模拟输入登录密码的选项,需要你输入密码,如果密码输入不对就重复输入:

新建一个脚本,命名为:sh08.sh

代码如下:

#!/bin/bash
try=3
read -p "Please enter your passwd: " mypasswd
while [ "$mypasswd" != 123456 ] && [ "$try" -gt 0 ]
do
        echo "Error!!!  Try again."
        read -p "Try again,left "$try" times: "
        let try-=1;

done
~    

运行脚本:


6.3.2.for...do...done (固定循环)

语法:

for var in con1 con2 con3 ...
do
           程序段
done

以上面的例子来说,这个 $var 的发量内容在循环工作时:
1. 第一次循环时, $var 的内容为 con1 ;
2. 第二次循环时, $var 的内容为 con2 ;
3. 第三次循环时, $var 的内容为 con3 ;
4. ....

例子1:

我们可以做个简单的练习。假设我有三种动物,分别是 dog, cat, elephant 三种, 我想每一行都输出这样:『There are dogs...』之类的字样,则可以如下代码:

新建一个脚本文件,命名为:sh09.sh

#!/bin/bash
for animal in dog cat elephant
do
        echo "There are ${animal}s...."
done 

运行脚本,执行三次循环:

例子:

打印:a1-a5,b1-b5,c1-c5,d1-d5

两重for循环,不使用脚本直接在屏幕上写for语句:

 


6.3.3.for...do...done 的数值处理

语法:

for (( 初始值; 限制值; 执行步阶 ))
do
          程序段
done

  初始值:某个变量在循环当中的起始值,直接以类似 i=1 设定好;
  限制值:当变量的值在这个限制刢值的范围内,就继续进行循环。例如 i<=100;
  执行步阶:每作一次循环时,变量值改变。例如 i=i+1。

例子:新建一个脚本程序,命名为:sh10.sh.程序让用户输入一个值,然后从1开始加到这个值,最后打印结果,例如输入10:就从1+2+3...+10;的结果打印出来,程序如下:

#!/bin/bash
sum=0
read -p "Please enter a number: " num
for((i=1;i<=$num;i++))
do

        sum=$(($sum+$i))
done
echo "The result is : $sum"

执行脚本:


 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值