Burnov

导航

使用结构化命令

  有一类名,容许脚本根据变量之的条件或者其他命令的结果跳过一些命令或者循环执行这些命令。这类命令我们通常称之为结构化命令;

1、使用if-then语句

  语句结构为:

    if command

    then

      commands

    fi

  如果if后执行命令正确,或者返回码为0,这执行then后面的命令。如果推出状态码不是0,那么then后面的命令将不会被执行;

#!/bin/bash
#testing the if statement
if date
then
    echo "it worked"
fi
chmod u+x test1
./test1

  date命令执行成功,则状态返回值为0,所以执行then后面的命令;

  另外一个实例:

#!/bin/bash
#testing a bad command
if asdfg
then 
    echo "it didn't work"
fi
echo "we're outside of th if statement"
chmod u+x test2
./test2

  asdfg的命令找不到,返回状态错误,则不会执行then后面的命令,直接跳到 fi 后面执行后面的echo命令。

  这里运行错误信息仍然会显示出来;

  then后面可以执行多条命令,如下面的实例:

#!/bin/bash
# testing multiple commands in the tehn section
testuser=rich
if grep $testuser /etc/passwd
then
    echo The bash files for user $testuser are:
    ls -a /home/$testuser/.b*
fi
chmod u+x test3
./test3

  打印出teacher用户的家目录下的相关的.b*文件

  if语句也可以将then写在if的同一排,如下:

    if command; then

      commands

    fi

2、if-then-else语句

  在if-then语句中,只能选择执行与否,而不能选择其他的命令来运行,这里我们就需要使用else;

    if command

    then

      commands

    else

      commands

    fi

  if后面的command执行成功,后面就执行then后的语句,如果返回值不是0则执行else后的语句;

#!/bin/bash
#testing the else section
testuser=badtest
if grep $testuser /etc/passwd
then
    echo The files for user $testuser area:
    ls -a /home/$testuser/.b*
else
    echo "The user name $testuser doesn't exist on this system"
fi
chmod u+x test4
./test4

  因为不存在badtest用户,返回值不为0,则执行else后语句;

  这样显然会更加友好

3、嵌套的if语句

  如果选择运行的结果不止两种,则可以通过elif来实现多种选项的执行;

    if command1

    then

      commands

    elif command2

    then

      more commands

    fi

  上面的方式还是有些许的麻烦,在工作中,我们经常使用下面的方式:if-then-elif组:

    if command1

    then

      command set 1

    elif command2

    then 

      command set 2

    elif command3

    then

      command set 3

    elif command4

    then

      command set 4

    fi

  命令执行,满足那个条件,则执行对应条件下的命令即可;

  但是这种使用方式依然很麻烦,而我们常用的则是case语句来实现这种需求,在后面我们会详细说道;

4、test命令

  test命令提供了一种检测if-then语句中不同条件的方法。如果test命令中列出的条件评估值为true,test命令以0退出转态码退出,这使if-then语句使用与其他编程语句中的if-then语句一样的方法运行。如果条件为false,则test命令退出,使得if-then与语句失败;

  test用法:test condition

  关联if-then的用法:

    if test condition

    then 

      commands

    fi

  bash shell提供了一种在if-then语句中申明test命令的另外一种用法

    if [ condition ]

    then

      commnads

    fi

  [] 中定义了test的条件 condition,注意:括号里面的condition前后都必须加一个空格符;

  test支持的命令评估方式有如下三种:

    1、数值比较

    2、字符串比较

    3、文件比较

  4.1、数值比较

    例子:

#!/bin/bash
#using numeric test comparisons
val1=10
val2=11

if [ $vall -gt 5 ]
then
    echo "The test value $val1 is greater then 5"
fi

fi [ $val1 -eq $val2 ]
then 
    echo "The values are equal"
else
    echo "The values are different"
fi

    第一个测试条件 $val1 -gt 5 val1的值是否大于5

    第二个测试条件 $val1 -eq $val2  val1的值是否等于val2的值

chmod u+x test5
./test5

    但是test数值条件有一个限制:

#!/bin/bash
#testing floating point numbers
val1=`echo "scale=4; 10 / 3" | bc`
echo "The test value is $val1"
if [ $val1 -gt 3 ]
then
    echo "The result is larger than 3"
fi
chmod u+x test6
./test6

    很显然val1输出的为一个浮点数,浮点数与整数进行运算就会出错;

  4.2、字符串比较

    1、字符串相等

#!/bin/bash
#testing string equality
testuser=rich

if [ $USER = $testuser ]
then
    echo "Welcome $testuser"
fi
chmod u+x test7
./test7

    $USER使用的为当前用户,与指定的变量$testuser相同,会执行后面的echo命令;

    类似的,也可以判断不相等:

#!/bin/bash
#testing string equality
testuser=baduser

if [ $USER != $testuser ]
then
    echo "This isn't $testuser"
else
    echo "Welcome $testuser"
fi
chmod u+x test8
./test8

    不相等则运行then后面的命令,如果相等,则运行else后面的命令;

    2、字符串顺序

    比较字符串大小的时候有两个问题:

      *大于号和小于号一定要进行转意,不然就默认认为是重定向符号;

      *大于和小于顺序与在sort命令中的顺序不同;

    这里,字符串大小比较是首字母的排序;

#!/bin/bash
#mis-using string comparisons

val1=baseball
val2=hockey

if [ $val1 > $val2 ]
then
    echo "$val1 is greater than $val2"
else
    echo "$val1 is less than $val2"
fi
chmod u+x badtest
./badtest

    重定向完成,没有错误,恢复状态码0,则运行then后面的命令;

    我们需要通过转意字符  \ 来解决这个问题;

#!/bin/bash
#mis-using string comparisons

val1=baseball
val2=hockey

if [ $val1 \> $val2 ]
then 
    echo "$val1 is greater than $val2"
else
    echo "$val1 is less than $val2"
fi
chmod u+x test9
./test9

    字符串的大小写的比较

#!/bin/bash
#testing string sort order
val1=Testing
val2=testing

if [ $val1 \> $val2 ]
then 
  echo "$val1 is greater than $val2"  
else
  echo "$val1 is less than $val2"  
fi
chmod u+x test10
./test10

    说明:小写字母要比大小字母大。

    3、字符串的大小

    评估一个变量是否包含数据的时候,通过-n和-z来比较就比较方便了

#!/bin/bash
#testing string length
val1=testing
val2=''

if [ -n $val1 ]  #val1的长度是否为非0
then
    echo "The string '$val1' is not empty"
else
    echo "The string '$val1' is empty"
fi

if [ -z $val2 ]  #val2的长度是否为0
then
    echo "The string '$val2' is empty"
else
    echo "The string '$val2' is not empty"
fi

if [ -z $val3 ]  #没有定义$val3,所以它的长度也是0
then
    echo "The string '$val3' is empty"
else
    echo "The string '$val3' is not empty"
fi
chmod u+x test10
./test10

  4.3、文件比较

    这是在我们脚本中最长使用的一类比较:

    1、检查目录

    -d 检测指定的文件是否存在于我们的系统中。

#!/bin/bash
#look before you leap
if [ -d $HOME ]
then 
    echo "Your HOME directory exists"
    cd $HOME
    ls -a
else
    echo "There's a problem with your HOME directory"
fi

    判断用户的home目录是否存在;

    2、查找对象是否存在

    -e 比较能够检查文件或者目录是否存在;

#!/bin/bash
#checking if a directory exists
if [ -e $HOME ]  #检查是否存在家目录
then
    echo "OK on the directory, now let's check the file"
    #Checking if a file exists
    if [ -e $HOME/testing ]  #检查家目录下的testing目录是否存在
    then
        #the file exists, append data to it 
        echo "Appending date to existing file"
        date >> $HOME/testing  #存在则追加数据
    else
        #the file doesn't exist,create a new file
        echo "Creating new file"
        date > $HOME/testing  #不存在则直接重定向数据到这个文件中即可
    fi
else
    echo "Sorry,you don't have a HOME directory"
fi

    3、检查文件

    -f 用来进行比较

#!/bin/bash
#check if a file
if [ -e $HOME ]  #判断家目录是否存在
then
    echo "The object exists, is it a file?"
    if [ -f $HOME ]  #如果存在,则判断他是否是一个文件
    then
        echo "Yes, it's a file!"
    else
        echo "No, it's not a file!"
        if [ -f $HOME/.bash_history ]  #判断$HOME/.bash_history是否为文件
        then
            echo "But this is a file!"
        fi
    fi
else
    echo "Sorroy,the object doesn't exist"
fi

    4、是否能读

    -r 判断文件是否具有刻度权限

#!/bin/bash
#testing if you can read a file
pwfile=/etc/shadow

#first ,test is the file exists,and is a file
if [ -f $pwfile ]
then
    #now test if you can read it 
    if [ -r $pwfile ]
    then
        tail $pwfile
    else
        echo "Sorry,I'm unable to read the $pwfile file"
    fi
else
    echo "Sorry,the file $pwfile doesn't exist"
fi

    5、检查空文件

    -s比较文件是否为空

#!/bin/bash
#testing if a file is empty
file=t15test
touch $file

if [ -e $file ]
then
    echo "The $file file exists and has data in it"
else
    echo "The $file exists and is empty"
fi

date > $file
if [ -s $file ]  #判断$file问价那种是否存在数据
then 
    echo "The $file file has data in it"
else
    echo "The $file is still empty"
fi

    6、检查是否能够向文件中写入数据

    -w 比较确定是否有权限向文件中写入数据

#!/bin/bash
#checking if a file is writeable

logfile=$HOME/t16test
touch $logfile
chmod u-w $logfile
now=`date +%Y%m%d-%H%M`

if [ -w $logfile ]  #判断$logfile是否有写权限
then
    echo "The program ran at: $now" > $logfile
    echo "The fist attempt succeeded"
else
    echo "The first attempt failed"
fi

chmod u+w $logfile
if [ -w $logfile ]
then 
    echo "The program ran at: $now" > $logfile
    echo "The second attempt succeeded"
else
    echo "The second attempt failed"
fi

    7、检查是否能够运行文件

    -x 判断文件是否具有执行权限

#!/bin/bash
#testing file execution
if [ -x test16 ]  #判断test16文件是否具有执行权限
then
    echo "You can run the script:"
    ./test16
else
    echo "Sorry,you are unable to execute the script"
fi

    8、检查所有权

    -O 比较可以容易的检查您是否是问价你的所有者

#!/bin/bash
#check file ownsership
if [ -O /etc/passwd ]
then
    echo "You're the ower of the /etc/passwd file"
else
    echo "Sorry,you're not the owner of th /etc/passwd file"
fi

    第一次在普通用户下检查则失败,之后切换到root用户下,就能成功;

    -G 检查文件的默认组,匹配默认组匹配成功,就正确;

#!/bin/bash
#check file group test

if [ -G $HOME/testing ]  #判断
then
    echo "You're in the same group as the file"
else
    echo "The file is not owned by your group"
fi
./test19
chgrp sharing $HOME/testing
./test19

    9、检查文件日期

    -nt 比较确定一个文件是否比另一个文件新

    -ot 比较确定一个文件是否比另一个文件更旧

#!/bin/bash
#testing file dates

if [ ./test19 -nt ./test18]
then
    echo "The test19 file is newer than test18"
else
    echo "The test18 file is newer than test19"
fi

if [ ./test17 -ot ./test19 ]
then
    echo "The test17 file is older than the test19 file"
fi

    如果正在检查的文件可以四处移动,则这个脚本就会出现问题,另一个问题是,这两个比较都不能用于检查文件是否一开始就存在。

#!/bin/bash
#testing file dates

if [ ./badfile1 -nt ./badfile2 ]
then
    echo "The badfile1 file is newer than badfile2"
else
    echo "The badfile2 file is newer than badfile1"
fi

    文件在不存在的时候,比较依然继续进行;

5、复合条件查找

  if-then语句可以使用布尔逻辑啦进行复合条件查找:

  [ condition1 ] && [ condition2 ]  #这个是and

  [ condition2 ] || [ condition2 ]  #这个是or

#!/bin/bash
#testing compound comparisons

if [ -d $HOME ] && [ -w $HOME/testing ]
then
    echo "The file exists and you can write to it "
else 
    echo "I can't write to the file"
fi

6、if-then的高级特征

  bash shell中最近新增加了两个比较新的功能,他们提供了可以在if-then语句中使用的高级功能:

  *双圆括号表示数学表达式

  *双方括号表示高级字符串处理函数

  6.1、使用双圆括号

    (( expression ))

    可以在if语句中使用双圆括号名,也可以使用普欧婷命令再脚本中进行赋值:

#!/bin/bash
#using double parenthesis

val1=10

if (( $val1 ** 2 > 90 ))
then 
    (( val2 = $val1 ** 2 ))
    echo "The sequare of $val1 is $val2"
fi

    在双圆括号中不必进行符号转意;

  6.2、使用双方括号

    [[ expression ]]  #模式匹配(pattern)

    在模式匹配中,可以定义字符串相匹配的正则表达式

#!/bin/bash
#using pattern matching
if [[ $USER == r* ]]
then
    echo "Hello $USER"
else
    echo "Sorroy,I don't know you"
if

7、case命令

  if-then-else,选项多了以后,会比较麻烦,代码执行效率会比较低;

  所以我们可以使用case语句来实现;

#!/bin/bash
#looking for a possible value

if [ $USER = "rich" ]
then
    echo "Welcome $USER"
    echo "Please enjoy your visit"
elif [ $USER = barbara ]
then
    echo "Welcome $USER"
    echo "Please enjoy your visit"
elif [ $USER = testing ]
then
    echo "Special testing account"
elif [ $USER = jessica ]
then
    echo "Don't forget to logout when you're done"
else
    echo "Sorry,you're not allowed here"
fi

  这样的代码运行效率比较低,每个选项都会进行比较

  case语句来实现这个功能;

    case variable in

    pattern1 | pattern2) commands1;;

    pattern3) commands2;;

    *) default commands;;

    esac

#!/bin/bash
#using the case command

case $USER in
rich | barbara)
    echo "Welcome,$USER"
    echo "Please enjoy your visit";;
testing)
    echo "Special testing account";;
jessica)
    echo "Don't forget to log off when you're done";;
*)
    echo "Sorry,you're not allowed here";;
esac

posted on 2019-04-28 12:25  Burnov  阅读(261)  评论(0编辑  收藏  举报