BASH编程基础之变量、条件判断

一、前言

在linux中,通常我们所指的脚本编程,指的是bash的脚本编程。

bash作为一种过程式的编程语言来说,它应该具备编程语言所应该具备的基本元素,即:变量,流程,函数,数组。今天我们介绍变量以及流程之一的条件判断。

二、变量

1、初识变量

在编程语言中,编程语言有两大种,强类型语言和弱类型语言。强类型语言中,要求变量的使用要严格符合定义,所有变量都必须先定义后使用。java、.NET、C++等都是强制类型定义的。与其相对应的是弱类型语言:数据类型可以被忽略的语言。它与强类型定义语言相反, 一个变量可以赋不同数据类型的值。

常见的数据类型有:
数值型:整形,浮点型,布尔型
字符型:单字符,字符串

bash属于弱类型语言,其默认的变量类型为字符型。

2、bash中的变量

我们知道,变量可以按其数据的类型进行划分,在bash中变量按其作用域的不同,也可以进行不同的划分。

  a) 局部变量:在bash脚本中,其作用域范围为局部性,比如想限制变量只在某函数中起作用

  b) 本地变量:在bash脚本中,其作用域范围为整个脚本,即脚本开始到结束

  c) 环境变量:系统工作使用的变量,常见的环境变量有,$PATH, $HOME, $PWD, 等等

  d) 位置参数变量:用于向脚本中传递参数

  e) 特殊变量:bash中预先定义好的具有特殊意义的比变量,如:$0, $1, $#, $@,….

3、bash中的变量的定义和使用

  a) 声明某变量为局部变量:local VAR_NAME=VALUE

  b) 声明某变量为本地变量:

    I) 不指定类型,默认类型为字符型  : VAR_NAEM=VALUE

    II) 定义数据类型为整数型:let VAR_NAME=VALUE 或 declare -i VAR_NAME=VALUE

    III) 声明某变量为环境变量:export VAR_NAME=VALUE 或 declare -x VAR_NAME=VALUE

三、第一个脚本

# vim script01.sh

# 编辑如下内容
#!/bin/bash
# Pragram: This is test scirpt.
# Author: FengYuxiu
# Version: 1.0
# History: 2015/06/29

echo "Hello World."

# 保存内容并退出
#
# bash -n script01.sh
# bash -x script01.sh

blob.png

显示执行过程,并执行成功,显示echo中的内容。

其中,在bash脚本中有一些规定好的规则
1、第一行为固定格式,#!/bin/bash, 表示这是一个bash的脚本,而不是一个普通的文本文件,让bash解释器执行以下语句。

2、# 为注释行,除了第一行中的#!/bin/bash

3、执行bash脚本的方法有两种,一个是给脚本加上执行权限,并指明执行路径,另一个是直接向bash命令传递脚本名,让bash解释执行脚本的内容

4、bash -n SCRIPT_NAME.sh 检查脚本的是否存在语法错误

5、bash -x SCRIPT_NAME.sh 查看脚本的执行过程,用于脚本排错

四、脚本的条件测试

说起条件测试,我们就想起布尔型,当然,测试的结果返回值只有两种,真或者假。其中在bash中0表示真,0以外表示假。

1、整数的测试:(整数A和B)

  A -gt B: A大于B

  A -lt B: A小于B

  A -eq B: A等于B

  A -ge B: A大于等于B

  A -le B: A大于等于B

  A -ne B: A不等于B

2、字符串测试:(字符串A和字符串B)

  A == B 或 A = B: 字符串等值比较

  A !=B : 不等于

  -z A: 判断A是否为空,空为真,不空为假

  -n A: 判断A是否为不空,不空为真,空为假

3、条件测试的方法:

  a) test 测试表达式

  b) [ 测试表达式 ] : []与于测试表达式之间必须要有一个半角空格,否则语法错误

  c) [[ 测试表达式 ]] : 等同于[ 测试表达式 ], 但有些特殊场合需要用到[[ 测试表达式 ]]

4、条件测试方法在脚本中的使用

if 条件表达式; then
    command1
    command2
    .....
fi

blob.png

当然,if的条件表达式可以嵌套,也可以进行多个条件判断

if 条件表达式; then
    command1
    command2
    if 条件表达式; then
        command3
        command4
        .....
    fi
elif  条件表达式; then
    command5
    command6
    ....
else
    commandN
fi

blob.png

五、基于if的条件测试脚本

练习1、向脚本中传递一个0-100的数字,85以上输出“A”,大于70小于85的输出“B”,大于60小于70的输出“C”,其他的输出“D”。

#!/bin/bash

# 初始化score的值
declare -i score=0
# 把参数1的值复制给score
score=$1

if [ $score -ge 85 ]; then
    echo "Rank is A."
elif [ $score -ge 70 ]; then
    echo "Rank is B."
elif [ $score -ge 60 ]; then
    echo "Rank is C."
else
    echo "Rank is D."
fi

blob.png

知识点补充:使用$1,$2, $N, 可以获取脚本的参数,没有传递时,获取为空值。

  $0表示执行的脚本名

  $#表示脚本参数的个数

  $@表示脚本的脚本的所有参数,数据结构为数组

  $*表示脚本的所有参数,数据结构为字符串

blob.png

练习2、在练习1的基础上,向脚本传递两个参数,参数1为用户名,参数2为分数,显示该学生所对应的等级。并且参数最少为2个,且第二个参数必须为数值。

#!/bin/bash

# 判断向脚本传递参数的个数,参数个数小于两个,返回错误并结束脚本。
if [ $# -lt 2 ]; then
    echo "The parameter is less than 2."
    exit 1
fi

# 判断参数2是否为数值,数值以外,显示错误,并退出脚本。
# 此处对数值没有进行精确判断,因此没有过滤以0开头的数值
if  ! echo "$2" | grep "[[:digit:]]\{1,\}" &> /dev/null ; then
    echo "Please input like ->> $0 name score" 
    exit 1
fi

declare -i score=0
name=$1
score=$2

if [ $score -ge 85 ]; then
    rank=A
elif [ $score -ge 70 ]; then
    rank=B
elif [ $score -ge 60 ]; then
    rank=C
else
    rank=D
fi

echo "${name}'s score is $rank"

blob.png

练习3、验证输入数值的正确性,分数的范围必须在0-100之间。

#!/bin/bash

declare -i score=0

if [ $# -lt 2 ]; then
    echo "The parameter is less than 2."
    exit 1
fi

if  echo "$2" | grep "[[:digit:]]\{1,\}" &> /dev/null ; then
    if [ $2 -ge 0 -a $2 -le 100 ]; then
        name=$1
        # 在把值复制给score变量前,用sed把前面的0都给去掉
        score=$(echo $2 | sed 's/^0*//')
        if [ $score -ge 85 ]; then
            rank=A
        elif [ $score -ge 70 ]; then
            rank=B
        elif [ $score -ge 60 ]; then
            rank=C
        else
            rank=D
        fi
        
        echo "${name}'s score is $rank"
    else
        echo "Please enter 0 to 100 points."
    fi
else
    echo "Please input like ->> $0 name score" 
    exit 1
fi

blob.png

六、基于case的条件测试脚本

case其实也可以说是简洁版的多跟支if语句。它的语法格式如下:

case 变量引用 in

PATTERN1)
    分支1
    ;;
PATTERN2)
    分支2
    ;;
    ......
*)
    分支n
    ;;
esca

blob.png

PATTERN表示的是匹配条件,具体格式如下:

  *:表示任意长度字符

  ?:任意单个字符

  [ ]:指定范围内的任意单个字符

  A|B:A或B

练习1、写一个脚本,向脚本传递一个参数,如cpu,mem,idisk(表示disk info),udisk(表示disk usage),显示相应参数所对应的信息。

#!/bin/bash

case $1 in
cpu)
    lscpu
    ;;
mem)
    free
    ;;
idisk)
    fdisk -l /dev/sd[a-z]
    ;;
udisk)
    df -h
    ;;
*)
    echo "Usage: $0 {cpu|mem|idisk|udisk}"
    ;;
esac

blob.png

blob.png

blob.png

blob.png

blob.png

七、条件测试知识扩展

1、字符串测试:

  "$A" =~ PATTERN: 如果变量中保存的字符串能被PATTERN匹配,则为真,否则为假

2、文件测试:

  -e $file : 判断文件是否存在,存在为真

  -f $file: 判断文件是否存在,且为普通文件,满足条件为真

  -d $file: 判断是否存在且为为目录

  -b $file: 判断是否存在且为块设备

  -c $file: 判断是否存在且为字符设备

  -S $file: 判断是否存在且为套接字设备

  -p $file: 判断是否存在且为管道设备

  -L $file: 判断是否存在且为符号链接文件

  -r,w,x $file: 判断用户是否对此文件有读,写,执行权限

  -u,g,k $file: 判断文件是否拥有suid,sgid, sticky的权限

  -O,-G $file: 判断当前用户是否为此文件的属主,属组

  $file1 -nt $file2: (new than) 判断文件1是否比文件2新

  $file1 -ot $file2: (old than) 判断文件1是否比文件2新

  $file1 -et $file2:  判断文件1是和文件是否为同一个文件的硬链接

blob.png

八、条件判断脚本的实战练习

功能:向脚本传递两个参数,第一个为fstab或bash,第2个参数为文件名,然后用vim打开对象文件编辑,并在用户保存退出文件时,对保存修改后的脚本进行语法检查。

#!/bin/bash
# Pragram: This is Grammar test script.
# Author: FengYuxiu
# Version: 1.0
# History: 2015/07/04

# 进行参数判断
if [ $# -lt 2 ]; then
    echo "Please enter an filename."
    exit 1
fi

filename=$2

# 判断文件是否存在
if [ ! -e $filename ]; then
    echo "file is not exits "
    read -p "Use the $filename to create new file.(yes/no): " yesno
    if [ ${yesno:=no} == "yes" -o $yesno == "y" ]; then
       touch $filename 
    else
       exit 1
   fi
fi

# 判断文件是否为普通文件
if [ ! -f $filename ]; then
    echo "Please enter ASCII text."
    exit 1
fi

case $1 in
bash|sh)
    vim $filename
    # 对文件进行语法检查,并把错误信息保存到errmsg变量中
    errmsg=$(bash -n $filename 2>&1)
    
    if [ -n "$errmsg" ]; then
        clear
        echo "$errmsg" 
        read -t 15 -p "Syntax error.Whether to modify.(yes/no): " isedit
        if [ ${isedit:no} == "yes" -o $isedit == "y" ]; then
            vim $filename
        fi
    fi
    
    # 因为是脚本,所以加上执行权限
    chmod u+x $filename
    ;;
fstab)
    vim $filename
    # 用mount -a 对挂载文件进行语法检测
    errmsg=$(mount -a 2>&1) 
    
    if [ -n "$errmsg" ]; then
        clear
        echo "$errmsg"
        read -t 15 -p "Syntax error.Whether to modify.(yes/no): " isedit
        if [ ${isedit:no} == "yes" -o $isedit == "y" ]; then
            vim $filename
        fi
    fi
    ;;
*)
    echo "Usage $0 {bash|sh|fstab} filename."
    exit 1
esac

clear
echo "$filename is save success."

1、执行脚本

blob.png

2、故意使脚本语法错误,保存并退出

blob.png

3、提示语法错误,并提示是否修改,输入yes回到vim界面修改,输入no结束,此处输入yes返回vim

blob.png

4、修改完成,保存并退出

blob.png

5、显示成功信息

blob.png

注意:此处的脚本只用到条件判断语句,没有用到循环,所以语法判断只能进行一次。

好了,以上的整理如有遗漏或错误,还请大神赐教。

原创文章,作者:封于修,如若转载,请注明出处:http://www.178linux.com/5977

(1)
封于修封于修
上一篇 2015-07-06
下一篇 2015-07-06

相关推荐

  • Linux基础—权限、grep使用

    今天主要是几个练习,内容如下: 1、复制/etc/skel目录为/home/tuser1,要求/home/tuser1及其内部文件的属组和其他用户均没有任何访问权限 [root@localhost ~]# cp -R /etc/skel/ /home/tuser1/ [root@localhost …

    Linux干货 2016-10-10
  • mysql5.6 GTID的实现以及maridb 10.9多主一从的架构

    一、MySQL 5.6 以后出现的GTID:     GTID概念:          1. GTID是一个由服务器的UUID和事务序号组成的唯一事务序号       &…

    Linux干货 2015-12-18
  • mv命令总结

    mv命令是move的缩写,可以用来移动文件或者将文件改名,是Linux系统下常用的命令,经常用来备份文件或者目录。 命令格式:mv  源文件或目录 目标文件或目录 2.命令功能:视mv命令中第二个参数类型的不同(是目标文件还是目标目录),mv命令将文件重命名或将其移至一个新的目录中。当第二个参数类型是文件时,mv命令完成文件重命名,此时,源文件只能…

    2017-07-24
  • 系统启动和内核管理(一)

    系统启动和内核管理(一)   (以CentOS5/6为例) 一、Linux的组成: 1、Linux:kernel+rootfs kernel:进程管理、内存管理、网络管理、驱动程序、文件系统、安全功能。 rootfs:程序和glibc 库:函数集合,function,调用接口(头文件负责描述); 过程调用,procedure,无返回值; 函数调用,…

    Linux干货 2016-09-10
  • Linux系统管理常用命令

    系统管理工具 进程的分类: CPU-Bound:CPU密集型,非交互。特别消耗CPU的,加密解密,压缩解压 IO-Bound:IO密集型,交互。大量的硬盘读写,例如复制文件 Linux系统状态的查看及管理工具:pstree, ps, pidof, pgrep, top, htop, glance, pmap, vmstat, dstat, kill, pki…

    Linux干货 2017-12-18
  • Homework Week-1 Linux基本

    1、描述计算机的组成及其功能。 计算机由硬件和软件组成;硬件主要分为五部分:控制器,运算器、存储器、输入和输出设备。软件分为系统软件和应用软件。 控制器(Control):是整个计算机的中枢神经,其功能是对程序规定的控制信息进行解释,根据其要求进行控制,调度程序、数据、地址,协调计算机各部分工作及内存与外设的访问等。 运算器(Datapath):运算器的功能…

    Linux干货 2016-08-15