《Linux系统》之"深入浅出"(六)shell script(续)

目录

一、shell script里常用的几个命令

1、expr命令

2、echo命令

3、printf命令

4、test命令

5、判断符号[]

二、流程控制语句

1、if分支结构

2、case..in语句

3、while循环结构

4、until循环结构

5、for循环结构

6、select表单循环

7、shift指令

三、函数的应用

四、script之间的引入

五、shell script的追踪与debug


一、shell script里常用的几个命令

1、expr命令

这个命令可以对整数表达式进行运算。注意,运算符前后必须要有空格符

[hyxy@master ~]$ expr 1 + 2
3
[hyxy@master ~]$ expr 12 - 10
2
[hyxy@master ~]$ expr 3 \* 4        <==乘号需要转义字符进行转义
12
[hyxy@master ~]$ expr 6 / 4         <==只能进行整除运算
1
[hyxy@master ~]$ expr `expr 3 + 9` / 3   <== 嵌套或者是给变量赋值时,使用反单引号
4
[hyxy@master ~]$ n=3
[hyxy@master ~]$ m=9
[hyxy@master ~]$ result=`expr \`expr $n + $m \` / 4`  <==反单引号嵌套时要使用转义字符
[hyxy@master ~]$ echo $result
3

或者使用选项可以对字符串进行一些计算

[hyxy@master ~]$ expr index "hello linux" ol     <==计算匹配字符第一次出现的位置序号,从1开始哦
3
[hyxy@master ~]$ expr substr "hello linux" 2 3  <==截取字符串,从第2个开始截取,截取3个长度
ell
[hyxy@master ~]$ expr length "hello linux"        <==计算字符串的长度
11
[hyxy@master ~]$ expr match “hello linux” "he"  <==计算两个字符串从头匹配上的字符个数
2

2、echo命令

echo命令用于输出显示一行数据。

[hyxy@master ~]$ name=kitty
[hyxy@master ~]$ echo $name
kitty
[hyxy@master ~]$ echo this is a test
this is a test

可以使用-e ,让转义字符串生效

[hyxy@master ~]$ echo "hello\nworld"
hello\nworld
[hyxy@master ~]$ echo -e "hello\nworld"         <== \n 表示换行      
hello
world
[hyxy@master ~]$ echo -e "hello\nworld\c"       <== \c 表示不换行
hello
world[hyxy@master ~]$ 

3、printf命令

与echo命令功能相同,用来输出显示数据。功能更强大,可以格式化字符串,指定字符串的宽度,左右对齐方式等等。默认情况下不换行,可以手动添加\n

语法:         printf     format    [arguments……...]
说明:         format:    格式控制字符串     
                    arguments:    参数值列表

格式控制字符 表示含义   转义字符 表示含义

%s

字符串

  \a 警告字符,通常为ASCII的BEL字符

%f

对应位置必须是浮点数。否则报错

  \b 后退

%c

ASCII字符,即显示对应参数的第一个字符

  \f 换页

%d,%i

十进制整数

  \n 换行

%o

八进制值

  \r 回车

%u

不带正负号的十进制值

  \t 水平制表符

%x

十六进制值(a-f)

  \v 垂直制表符

%X

十六进制值(A-F)

  \\ 表示\本身

%%

表示%本身

     

直接看示范案例:

[hyxy@master ~]$ printf "%s\n" 1 2 3 10
1
2
3
10
[hyxy@master ~]$ printf "%.2f\n" 1 2 3 10
1.00
2.00
3.00
10.00
[hyxy@master ~]$ printf " (%s) " 1 2 3 10;echo
 (1)  (2)  (3)  (10)
[hyxy@master ~]$ printf "%s %s %s\n" 1 2 3 4     <==#多出的参数会重用之前的格式
1 2 3
4  
[hyxy@master ~]$ printf "%-10s %-10s %-4s %-4s \n" 姓名 性别 年龄 体重kg 张三 男 23 70 王红 女 18 45
姓名     性别     年龄 体重kg 
张三     男        23   70   
王红     女        18   45 
[hyxy@master ~]$ printf "%x\n" 43          <==将十进制43转成十六进制
2b

4、test命令

用于检测文件类型、文件属性、整数、字符串等操作

文件类型检测
test   -e   filename 检测filename是否存在
test   -d   filename 检测filename是不是目录
test   -f   filename 检测filename是不是普通文件
test   -L   filename 检测filename是不是软链接文件
文件属性检测
test   -r   filename 检测filename是否有可读权限
test   -w   filename 检测filename是否有可写权限
test   -x   filename 检测filename是否有执行权限
两个文件的比较
test   file1  -nt  file2 检测 file1 是否比 file2 新
test   file1  -ot  file2 检测 file1 是否比 file2 旧
test   file1  -ef  file2 检测 file1和 file2 是否为同一文件
两个整数的比较
test  n1  -eq  n2 检测 n1 与 n2 是否相等
test  n1  -ne  n2 检测n1 与 n2 是否不等
test   n1   -gt  n2 检测n1 是否大于 n2 (greater than)
test   n1   -lt   n2 检测n1 是否小于 n2 (less  than)
test   n1  -ge  n2 检测n1 是否大于等于n2
test   n1   -le   n2 检测n1 是否小于等于n2
字符串的数据
test   -z   string 检测string  是否为空
test   -n   string 检测string  是否不为空  -n  也可以省略
test    string1  ==  string2 检测string1与string2是否相等
test    string1  !=  string2 检测string1与string2 是否不想等
多条件连接     test   -r  filename  -a   -x  filename
 -a and,两个检测都成立,返回true
-o or,只要有一个检测成立,就返回true
!

通常test命令不单独使用,而是与if语句连用,或者是放在循环结构中。

5、判断符号[]

除了好用的test外,我们还可以使用中括号来进行检测条件是否成立。

举例说明

[  -r  filename ]    :   检测filename是否有可读权限

[  -f  filename -a  -r  filename   :   检测filename是不是普通文件并且有可读权限

二、流程控制语句

shell script中,也支持像其他编程语言常用到的流程控制语句,如if,while等等。

1、if分支结构

只有一个条件表达式的写法:

写法1:
if  [   条件表达式  ]  ;then
           #
条件成立时,要执行的作业内容
fi

写法2:
if  [   条件表达式  ]  ;then
           #
条件成立时,要执行的作业内容
else
           #条件不成立时,要执行的作业内容
fi

if中的判断符号后的分号[;],也可以使用[enter]键来替换。 fi是if的倒写形式,是if分支结构结束的含义。

[hyxy@master ~]$ vim test.sh
#!/bin/bash
if [ -d "/home" ];then
        echo "this is a directory"
else
        echo "this is not a directory"
fi

[hyxy@master ~]$ sh test.sh
this is a directory

有多个条件表达式的写法:

if  [   条件表达式1  ]  ;then
           #
条件1成立时,要执行的作业内容
elif  [  条件表达式2  ] ;then
           #条件2成立时,要执行的作业内容
fi

[hyxy@master ~]$ vim test.sh
#!/bin/bash
m=10 n=11 x=4 y=5
if [ $m -gt $n ];then
        echo "m>n" 
elif [ $m -lt $n -a $x -lt $y ];then      #多条件可以使用 -a/-o连接
        echo "m<n&&x<y"
elif [ $m -le $n ] || [$x -eq $y ];then   #每个条件一个[],使用&&/||连接
        echo "m<=n&&x<=y"
fi
[hyxy@master ~]$ sh test.sh
m<n&&x<y

当然可以嵌套使用,这里就不举例了。

2、case..in语句

也可以利用case..in语句,进行匹配,选择匹配成功的那块进行作业。

格式:

case  $variable  in
值1)
             #作业内容
;;                                             <==两个分号,表示这个作业结束
值2)
             #作业内容
;;
esac 
                                      <==esac是倒着写的case,结束case..in结构的作用

[hyxy@master ~]$ vim test.sh
#!/bin/bash
case $1 in
"hello")
        echo "hello,welcome to china"
;;
"")
        echo "you must input parameters"
;;
*)                                      # 通配符*
        echo "your command is $0"
;;
esac
[hyxy@master ~]$ sh test.sh
you must input parameters

3、while循环结构

while循环结构:当条件成立时,就循环执行作业内容。

格式:

while  [  条件表达式  ]
do

             #作业内容
done

[hyxy@master ~]$ vim test.sh
#!/bin/bash
while [ "${input}" != "yes" -a "${input}" != "YES" ]
do
        read -p "please input yes/YES to stop:" input
done
        echo "your input is :${input}"
[hyxy@master ~]$ sh test.sh
please input yes/YES to stop:hello
please input yes/YES to stop:kitty
please input yes/YES to stop:yes        #输入yes终止循环
your input is :yes

4、until循环结构

until循环结构:当条件成立时,就终止循环,条件不成立时,就一直循环下去。

格式:

until  [  条件表达式  ]
do
          #
作业内容
done

我们使用until循环结构修改while循环结构的案例:

[hyxy@master ~]$ vim test.sh
#!/bin/bash
until [ "${input}" == "yes" -o "${input}" == "YES" ]
do
        read -p "please input yes/YES to stop:" input
done
        echo "your input is :${input}" 
[hyxy@master ~]$ sh test.sh
please input yes/YES to stop:a
please input yes/YES to stop:b
please input yes/YES to stop:yes
your input is :yes

在循环结构中,我们使用以下两个关键字:

break:  如果想要提前结束循环(即想跳出循环) 使用关键字
continue:  如果想结束当次循环,进行下一次循环 使用关键字

[hyxy@master ~]$ vim test.sh
#!/bin/bash
num=1
until [ "${input}" == "yes" -o "${input}" == "YES" ]
do
        read -p "please input yes/YES to stop:" input
        let num++
        if [ $num -gt 5 ];then
                echo "your count of input is out of 10,auto stop"
                break           <== 跳出,结束循环
        fi
done
        echo "your input is :${input}"
[hyxy@master ~]$ sh test.sh
please input yes/YES to stop:1
please input yes/YES to stop:1
please input yes/YES to stop:1
please input yes/YES to stop:1
please input yes/YES to stop:1
your count of input is out of 10,auto stop
your input is :1

5、for循环结构

while,until循环结构适合不知道循环次数的情况。而知道循环次数的情况下,for循环结构就比较合适了

语法:

for  variable  in   列表
do

              #作业内容
done

直接上案例

#!/bin/bash
for day in monday tuesday wenseday thursday friday saturday sunday
do
      echo " today is $day"
done

#!/bin/bash
files=$(ls ~)
for filename in ${files}
do
        echo "filename is $filename"
done
#!/bin/bash
for num in $(seq 1 100)
do
      echo "$num"
done
#!/bin/bash
for username in $(cut -d ':' -f1 /etc/passwd)
do
        echo "username is :$username"
done

for循环还有另外一种写法,适合在数值的处理上使用
格式:

for ((  变量初始化条件限定变量改变方向 ))
do
          #作业内容
done

#!/bin/bash
sum=0
for ((i=0;i<=10;i++))
do
     #sum=$[ $sum + $i ]
     sum=$(( $sum + $i ))
done
echo $sum

6、select表单循环

有的时候,需要将一些数据设置成表单的模式,供用户来选择。我们就可以使用select表单循环结构

格式:

for variable in  列表
do
          #作业内容
done

也直接上案例演示

#!/bin/bash
select var in monday tuesday wenseday thursday friday saturday sunday
do
   echo "your option is $var"
   if [ $var == "sunday" ];then
           break
   fi
done
[hyxy@master ~]$ sh test.sh
1) monday    3) wenseday  5) friday    7) sunday
2) tuesday   4) thursday  6) saturday
#? 2
your option is tuesday
#? 1
your option is monday
#? 2
your option is tuesday
#? 7
your option is sunday            #然后退出
[hyxy@master ~]$

7、shift指令

shift这个单词,在计算机中,有“使数据产生位移”的含义。对于linux系统来说,在shell中,shift命令可以使参数产生位移。我通过案例来给大家解释一下:

[hyxy@master ~]$ vim test.sh
#!/bin/bash
echo "all parameters ========>: $@"
echo "the first parameters ==>: $1"
echo "---------------------黄金分割线---------------------------"
shift
echo "all parameters ========>: $@"
echo "the first parameters ==>: $1"
echo "---------------------黄金分割线---------------------------"
shift
echo "all parameters ========>: $@"
echo "the first parameters ==>: $1"
echo "---------------------黄金分割线---------------------------"
shift
echo "all parameters ========>: $@"
echo "the first parameters ==>: $1"

运行这个shell script,试试看

[hyxy@master ~]$ sh test.sh  one two three four   #四个参数
all parameters ========>: one two three four
the first parameters ==>: one
---------------------黄金分割线---------------------------
all parameters ========>: two three four         #shift后,剩下三个参数
the first parameters ==>: two
---------------------黄金分割线---------------------------
all parameters ========>: three four             #shift后,剩下两个个参数
the first parameters ==>: three
---------------------黄金分割线---------------------------
all parameters ========>: four                   #shift后,剩下一个参数
the first parameters ==>: four

再看看这个案例:计算参数的总和

[hyxy@master ~]$ vim test.sh
#!/bin/bash
sum=0
until [ "$1" == "" ]
do
     sum=`expr $sum + $1 `
     shift                  #使参数向左移动
done
echo "sum:$sum"

运行结果如下:

[hyxy@master ~]$ sh test.sh  1 2 3 4 
sum:10

三、函数的应用

在shell script中,也支持函数的使用,这样可以更方便重用作业逻辑,简化我们的程序代码

格式:

function  funcName(){                                 
               #作业内容
}

注意:

1、关键字function 可加可不加
2、调用时,直接写函数名称,不添加()。
3、因为script是从上往下,从左往右执行的,所以,要先定义,后调用
4、return关键字,可加可不加,看需求
          加的话,返回值只能是0~255的整数,使用$?获取返回值
6、可以使用$n位置参数变量向函数里传值

看案例,来学习是最简单有效的方式哦!

应用案例1:

#!/bin/bash
function sum(){
  a=0
  for i in {1..100}
  do
     a=$[a+i]
  done
  echo "1~100 的和:$a"
}
sum        # 调用函数sum

[hyxy@master ~]$ sh test.sh   #执行script
1~100 的和:5050


[hyxy@master ~]$ source ./test.sh   #另外一种执行方式
1~100 的和:5050
[hyxy@master ~]$ sum      #因为test.sh已经引入此bash中,因此可以直接写函数调用了,是不是很方便
1~100 的和:5050

应用案例2:

#!/bin/bash
function f1(){
  sum=0
  for i in {1..100}
	do
	sum=$[sum+i]
  done
  echo "sum的结果是:$sum "
  x=200
  y=2
  return $[x+y]       #可以带有return关键字,规定函数的返回值
}
f1                    #调用函数
result=$?             #调用后函数的返回值,必须使用$?来读取
echo "result:$result"

[hyxy@master ~]$ sh test.sh
sum的结果是:5050
result:202            #函数的返回结果

这里强调一下:函数的返回值的范围:0~255。不会超过这个范围的。

应用案例3:

#!/bin/bash
function pr(){
        echo -n "your choise is "
}
echo "this programe is print your choise"
select var in monday tuesday wenseday thursday friday saturday sunday q
do
       pr; echo $var
       if [ "$var"  ==  "q" ] ;then
             break
       fi
done

[hyxy@master ~]$ sh test.sh
this programe is print your choise
1) monday    3) wenseday  5) friday    7) sunday
2) tuesday   4) thursday  6) saturday  8) q
#? 1
your choise is monday
#? 2
your choise is tuesday
#? 8
your choise is q

应用案例4:

#!/bin/bash
function f1(){
    sum=$[ $1 + $2 ]
    return $sum
}
f1 10 20
echo "f1执行结果:$?"


[hyxy@master ~]$ sh test.sh
f1执行结果:30

[hyxy@master ~]$ source ./test.sh   #将脚本引入bash环境下
f1执行结果:30
[hyxy@master ~]$ f1 20 40    #函数可以看成命令来执行
[hyxy@master ~]$ echo $?
60

四、script之间的引入

shell script内部也可以引用其他外部脚本,这样可以很方便的封装一些公用的代码作为一个独立的文件。

shell script引用外部脚本语法如下:  

.    fileName                      #   .与文件之间一定要有空格
或者
source    fileName

看下面案例:

1、在test.sh里定义函数f1

[hyxy@master ~]$ vim test.sh    #在test.sh定义一个函数
#!/bin/bash
function f1(){
    sum=$[ $1 + $2 ]
    echo "sum of the two number is:$sum"
}

2、在test1.sh里引入test.sh

[hyxy@master ~]$ vim test1.sh    
#!/bin/bash
. ~/test.sh           #在test1.sh里引入test.sh脚本
f1 10 10              #使用test.sh里的函数f1

3、执行test1.sh

[hyxy@master ~]$ sh test1.sh
sum of the two number is:20     #函数f1的逻辑

五、shell script的追踪与debug

我们可以使用下面的语法来进行脚本的追踪与debug

sh   [选项]   *.sh

选项介绍:

-n:不执行script,仅仅检查语法的问题

-v:不执行script,仅仅将script里的内容显示在屏幕上

-x:显示script里的重要数据,并执行script

[hyxy@master ~]$ vim test.sh
#!/bin/bash
function f1(){
    sum=$[ $1 + $2 ]
    echo "sum of the two number is:$sum"
}
name=nihao
yn=yes
for var in one two three
do
    echo $var
done

测试一下:


[hyxy@master ~]$ sh -x test.sh
+ name=nihao
+ yn=yes
+ for var in one two three
+ echo one
one                           
+ for var in one two three
+ echo two
two
+ for var in one two three
+ echo three
three

小总结:到这里 shell script就整理完了,在shell编程上,要多看,多练,才会更加纯熟。

猜你喜欢

转载自blog.csdn.net/Michael__One/article/details/85521700