Shell脚本编程快速上手

一、认识shell

操作系统最外层的程序,shell通过提示符让用户输入,向操作系统解释该输入,然后处理来自操作系统的任何结果输出来,管理用户与操作系统之间的交互。

 

 

二、shell脚本编程

这里我们直接上手编程,再根据遇到的问题逐个讲解。

shell脚本编写流程:

1)创建shell脚本文件

2)编写shell脚本

3)给脚本文件添加执行权限

4)执行shell脚本文件

 

2.1 创建shell脚本文件

这里我们可以用gedit、kedit、vim、vi等等编辑软件创建shell脚本文件,注意文件后缀名为“ .sh ”。

 

2.2 编写shell脚本

以下面程序为例:

#!/bin/bash

#程序作用,定义变量,给变量赋值,键盘输入变量的值,并且在屏幕中打印变量的值

VAR1=0                    #定义变量VAR1 并赋初值0
VAR2=0                    #定义变量VAR2 并赋初值0

echo "请输入VAR1的值:"    #在屏幕上打印   请输入VAR1的值:

read VAR1                 #从键盘获取VAR1的值

echo "VAR1 = ${VAR1}"     

VAR2=${VAR1}              #取VAR1的值,并且赋给VAR2

echo "VAR2 = ${VAR2}"

我们以C语言程序来进行对比讲解,shell脚本的特点。

首先第一行的 #!/bin/bash 就相当于C语言中的添加头文件#include <stdio.h>,常见的shell类型有/bin/sh,/bin/csh,/bin/ksh以及我们这里选择的:/bin/bash,其中bash是大多数linux默认的shell程序。

这里我们也看到了注释文字之前都是以#开头的,没错,在shell脚本中,我们是以#为注释标号

在紧接着我们定义了VAR1和VAR2两个变量,并且赋了初值0,这里我们需要注意,变量赋值的时候,“ = ”两边不能有空格

变量赋值的格式为:     变量名=值      (等号两端不能有空格)

echo是一个打印指令,将数据打印到指定的输出流当中,默认是屏幕。

read则是键盘输入数据传送给变量,想当于C语言中的scanf()函数。

VAR2=${VAR1},这行代码执行了两件事,先取了VAR1的值,然后再将VAR1的值赋给了VAR2,这里我们需要注意关于变量的取值,虽然在变量名前加一个" $ "就可以取得变量的值,但是这样的取值方法很容易出现错误,例如:

SCORE=80

echo "your score is $SCOREcredits"

这里的打印结果将是:your score is               而不是我们预料的:your score is 80credits   因为shell并不会自己去搜索变量,所以shell自动的将SCOREcredits当成了一个变量并且去取了他的值取显示。所以我们要对取值命令写得更谨慎一些:

SCORE=80

echo "your score is ${SCORE}credits"

 

2.3 给shell脚本文件添加执行权限

在上面我们已经编写并保存了一个极简单的shell脚本文件,但是此时的shell脚本文件是没有执行权限的,我们需要手动给shell脚本文件添加执行权限指令如下:

chmod +x 文件名.sh

2.4 执行shell脚本文件

执行完上面3个步骤以后,我们就可以在Ubuntu终端上直接只执行shell脚本文件了,执行结果如下:

 

三、shell脚本的基本语法

3.1 变量

在shell编程中,shell的变量都是字符串组成,无具体类型,其中/bin/bash中有以下具体四种变量。

1)用户自定义变量

2)位置变量

3)预定义变量

4)环境变量

 

3.1.1 用户自定义变量

用户自定义的变量由字母或下划线开头,由字母,数字或下划线序列组成,并且大小写字母意义不同,变量名长度没有限制。习惯上用大写字母来命名变量。变量名以字母表示的字符开头,不能用数字。

3.1.2 位置变量

位置变量指的是命令行参数,例如C语言中的main()函数传参,传入的参数即为位置变量(./a.out   参数1  参数2....),这里我们在shell脚本中调用位置变量的时候,只需使用" $n "即可,其中n代表的是第几个参数,$1 是传入的参数1,$2是传入的参数2,以此类推使用。

3.1.3 预定义变量

$0    与键入的命令行一样,包含脚本文件名
       $1,$2,……$9  分别包含第一个到第九个命令行参数
       $#    包含命令行参数的个数
       $@    包含所有命令行参数:“$1,$2,……$9”
       $?    包含前一个命令的退出状态
       $*    包含所有命令行参数:“$1,$2,……$9”
       $$    包含正在执行进程的ID号

3.1.4 环境变量

环境变量即是linux系统中的环境变量,该处变量在$HOME/.profile文件中有定义。

 

3.2 功能性语句

3.2.1 算术运算

在shell脚本编程中能使用的算术运算符(+),(-),(\*),(/),(%),(=),(**)等等,并且我们在使用算术运算的时候要先写算术命令expr并且整个语句要使用命令置换,就是键盘左上角的数字1旁边的那个按键,反引号。

 +:VAR=`expr 10   +  2`  #加    结果为12
 -:VAR=`expr 10   -  2`  #减    结果为8
\*:VAR=`expr 10  \*  2`  #乘    结果为20
 /:VAR=`expr 10   /  2`  #除    结果为5
 %:VAR=`expr 10   %  2`  #取余  结果为0
**:VAR=`expr 10  **  2`  #乘方  结果为100

3.2.2 关系运算

这里有一个细节需要我们注意一下,在shell脚本编程中,关系运算结果0为真,结果1为假

#字符串相关
           s1  = s2 	测试两个字符串的内容是否完全一样
           s1 != s2     测试两个字符串的内容是否有差异
           -z    s1 	测试s1 字符串的长度是否为0
           -n    s1 	测试s1 字符串的长度是否不为0
#整数相关
            a -eq b 	测试a 与b 是否相等
            a -ne b     测试a 与b 是否不相等
            a -gt b 	测试a 是否大于b
            a -ge b 	测试a 是否大于等于b
            a -lt b 	测试a 是否小于b
            a -le b 	测试a 是否小于等于b
#文件相关
            -d name     测试name 是否为一个目录
            -f name 	测试name 是否为普通文件
            -L name     测试name 是否为符号链接
            -r name 	测试name 文件是否存在且为可读
            -w name 	测试name 文件是否存在且为可写
            -x name 	测试name 文件是否存在且为可执行
            -s name 	测试name 文件是否存在且其长度不为0
            f1 -nt f2 	测试文件f1 是否比文件f2 更新
            f1 -ot f2 	测试文件f1 是否比文件f2 更旧

在进行关系运算的时候,我们需要调用test命令,调用格式为:test  表达式1  运算符  表达式2  

#调用格式:     test  表达式1  运算符  表达式2  

VAR1=10
VAR2=20

test  ${VAR1}  -gt  ${VAR2}   #判断VAR1是否大于VAR2  结果为1

# test命令可以使用 [] 进行替代,上式可以写为

[ ${VAR1} -gt ${VAR2} ]

 

3.3 结构性语句

3.3.1 选择结构

1. 
      if    表达式
            then  
            ... ...   #条件满足执行的任务
      fi 

    
例:
      if [ ${VAR1} -gt ${VAR2} ]
            then
            echo "VAR1 > VAR2"
      fi
		
 
		
2. 
      if    表达式
            then 
            ... ...   #条件满足执行的任务  
      else  
            ... ...   #条件满足执行的任务
      fi


例:
      if [ ${VAR1} -gt ${VAR2} ]
            then
            echo "VAR1 > VAR2"
      else 
            echo "VAR1 < VAR2"
      fi


3.  
      if    表达式1
            then 
            ... ...   #条件满足执行的任务 

      elif  表达式2				
            then 
            ... ...   #条件满足执行的任务 

      else  
            ... ...   #条件满足执行的任务 
      fi


例:
      if [ ${VAR1} -gt ${VAR2} ]
            then
            echo "VAR1 > VAR2"

      elif  [ ${VAR1} -eq ${VAR2} ]
            
            then 
            echo "VAR1 = VAR2"

      else
            echo "VAR1 < VAR2"
      fi


4.  
      case   字符串变量   in
      模式1)
             ... ...   #条件满足执行的任务 
             ;;

      模式2)
             ... ...   #条件满足执行的任务 
             ;;
      .
      .
      .

      模式n)
             ... ...   #条件满足执行的任务 
             ;;
      esac

3.3.1 循环结构

#循环结构
1. 
    for var in item1 item2 ... itemN
    do
        ... ... #条件满足执行任务

    done

例.
    for i in 1 2 3 4 5 6 7 8
    do
        echo ${i}
    done

2. 
    for (( i = 1; i < 101; i++ ))
    do 
        ... ... #条件满足执行任务 
    done 

例.。
    for ((i = 1; i < 101; i++))
    do
        echo ${i}
    done


3. 
    for var //这里的var的值是位置变量
    do 
        ... ... #条件满足执行任务
    done



4. 
    while 判断命令或表达式
    do
        ... ... #条件满足执行任务
    done


例:
    while [ $i -lt 100 ]
    do 
        echo ${i}
    done    



5. 死循环
    while true
    do 
        ... ... #条件满足执行任务
    done

    for ((; ;))
    do
        ... ... #条件满足执行任务
    done


6. break 和 continue 
    continue    #跳过该次循序
    break       #跳出该循环体  

    continue  n #跳出最近n层循环语句
    break  n    #跳出最近n层循环体

 

3.4 shell函数

在shell编程中,函数在调用前必须先定义,即在顺序上函数说明必须放在调用程序的前面。调用程序可以传递参数给函数,函数可用return语句把运行结果返回给调用函数,函数只能在当前shell中起作用,不能输出到子shell中。

函数定义格式如下:

#方式一:

function func_name()
{
    commond1
    ...  ...
    commond2
}


#方式二:

func_name()
{
    commond1
    ...  ...
    commond2
}

函数调用的时候直接写函数名即可,函数中写的return返回值只能通过 " $? " 获取,若是调用函数将函数赋值给变量如:

(var = `func_name`),var得到的结果将是func_name函数中echo命令打印的内容。

func_name()
{
    echo "RESULT = $1 + $2"
    
    return `expr $1 + $2`
}

VAR1=10                                                    
VAR2=20

func_name ${VAR1} ${VAR2}    #${VAR1} ${VAR2} 就是函数参数$1 和 $2

RESULT=`func_name ${VAR1} ${VAR2}`

echo $?            

echo $RESULT

程序运行结果如下:程序return的返回值是通过 " $? " 得到,而赋给变量的值确实函数中echo输出的结果,在这里变量RESULT起到的是一个缓冲区的作用。

 

3.5 在shell脚本中调用其他shell脚本

这个只需要将被调用的shell脚本放到一个路径下,并且在程序中需要调用的地方书写source filename.sh 即可。

 

仓促成文,不当之处,尚祈方家和读者批评指正。联系邮箱1772348223@qq.com 

 


版权声明:本文为qq_35600620原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。