海哥 发表于 2024-7-20 02:04:04

[Linux][Shell][Shell逻辑控制]详细教学

1.if 判断

1.if-then



[*]语法:if command
then
        command
fi

[*]bash的if语句和其他编程语言不一样,bash的if语句会直接运⾏if后⾯的命令

[*]如果该命令执⾏正确(状态码为0),处于then的命令就会被执⾏
[*]否则就不会执行,或者执行其他逻辑的语句,最后到fi结束逻辑控制

2.if-then-else



[*]语法:if command
then
        command
else
        command
fi

3.elif



[*]语法
if commandthen        commandelif command
then
        command
fi
4.case



[*]可以取代多if-else分支case "变量" in
值1)
命令
;;
值2)
命令2
;;
*)
命令

5.现实上手



[*]内存监控#!/bin/bash

FreeMem=`free -m | awk 'NR==2 {print $NF}'`
CHARS="Current memory is $FreeMem"

if [ "$FreeMem" -lt 16000 ]
then
    echo $CHARS
    echo "内存不足,抓紧维护服务器!"
fi

[*]读取比力巨细

[*]单分支版本#!/bin/bash

a=$1
b=$2

if [ $a -lt $b ]
then
    echo "Yes, $a less than $b"
    exit 0
fi

if [ $a -eq $b ]
then
    echo "Yes, $a equal $b"
    exit 0
fi

if [ $a -gt $b ]
then
    echo "Yes, $a greater than $b"
    exit 0
fi

[*]多分支版本#!/bin/bash

a=$1
b=$2

if [ $a -lt $b ]
then
    echo "Yes, $a less than $b"
    exit 0
elif [ $a -eq $b ]
then
    echo "Yes, $a equal $b"
    exit 0
else [ $a -gt $b ]
    echo "Yes, $a greater than $b"
    exit 0
fi


[*]MySQL监控脚本#!/bin/bash

if [ `netstat -tunlp | grep mysql | wc -l` -ge "1" ]
then
    echo "MySQL is running"
else
    echo "MySQL is stopped"
    # systemctl start mysql.service
fi

[*]Rsync启动脚本#!/bin/bash

if [ "$#" -ne 1 ]
then
    echo "Usage: $0 {start|stop|restart}"
    exit 1
fi

if [ "$1" = "start" ]
then
    /usr/bin/rsync --daemon
    sleep 2

    if [ `netstat -tunlp | grep rsync | wc -l` -ge 1 ]
    then
      echo "Rsync is started"
      exit 0
    fi
elif [ "$1" = "stop" ]
then
    killall rsync &>/dev/null
    sleep 2

    if [ `netstat -tunlp | grep rsync | wc -l` -eq 0 ]
    then
      echo "Rsync is stopped"
      exit 0
    fi
elif [ "$1" = "restart" ]
then
    kill rsync
    sleep 1

    killpro=`netstat -tunlp | grep rsync | wc -l`
    /usr/bin/rsync --daemon
    sleep 1

    startpro=`netstat -tunlp | grep rsync | wc -l`

    if [ "$killpro" -eq 0 -a "$startpro" -ge 1 ]
    then
      echo "Rsync is restarted"
      exit 0
    fi
else
    echo "Usage: $0 {start|stop|restart}"
    exit 1
fi

2.条件测试

0.事前说明



[*] 条件测试常用的语法
https://i-blog.csdnimg.cn/direct/ba5e4f2636f447d7b6ce2f6960dd99ba.png
[*] 常用字符串测试操作符
https://i-blog.csdnimg.cn/direct/d0284b93f4d24629bb8d64c720cb64b7.png
[*] 数值比力
https://i-blog.csdnimg.cn/direct/3ef5497874a84102a240ac9301e1e7eb.png
[*] 逻辑操作符
https://i-blog.csdnimg.cn/direct/e53a888339aa4f4794ec8f7633ef45ba.png
[*] 各命令对照表
https://i-blog.csdnimg.cn/direct/730ecebffc184780a28da2a79dfafd7d.png
1.test 命令



[*]test命令最短的定义可能是评估⼀个表达式

[*]如果条件为真,则返回⼀个0值
[*]如果表达式不为真,则返回⼀个⼤于0的值—,也可以将其称为假值
[*]检查最后所执⾏命令的状态的最轻巧⽅法是使⽤$?值

[*]参数:

[*] 关于某个文件名的类型侦测(存在与否),如:test -e filename
   参数意义-e该 文件名 是否存在-f该 文件名 是否为文件(file)-d该 文件名 是否为目次(directory)-b该 文件名 是否为block device装置-c该 文件名 是否为一个character device装置-S该 文件名 是否为一个Socket文件-p该 文件名 是否为一个FIFO(pile)文件-L该 文件名 是否为一个毗连档
[*] 关于文件的权限侦测,如:test -r filename
   参数意义-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是否为同⼀⽂件,可⽤在硬链接的判断上
重要意义在判断,两个⽂件是否均指向同⼀个inode
[*] 关于两个整数之间的判断,如:test num1 -eq num2
   参数意义-eq两数相当-ne两数不相当-gtnum1大于num2-ltnum1小于num2-genum1大于等于num2-lenum1小于等于num2
[*] 判断字符串的数据
   参数意义-z为空串,则返回true-n不为空串,则为true=str1 == str2,则返回true!=str1 != str2,则返回true
[*] 多重条件判断,如:test -r filename -a -x filename
   参数意义-a(and)两状态同时成立-o(or)两状态任何一个成立!逻辑取反

2.[]



[*]脚本中经常举行条件测试,用的最多的,就是中括号[]
[*]test和[]的作用是一样的
[*]根本要素:

[*][]两个符号,左右都要有空格分隔
[*]内部操作符与操作变量之间要有空格,如:[ "a" = "b" ]
[*]字符串比力中,> <需要写成\> /<举行转义
[*][]中字符串或者${}变量只管利用""双引号括住,制止值未定义引用[ -n "$filename" ]

[*][]中可以利用-a -o举行逻辑运算,不支持&& ||
[*][]是bash内置命令

3.双括号

1.(())



[*]bash支持双小括号,写入高级数学表达式
2.[[]]



[*]双中括号提供了针对字符串的⾼级特性,模式匹配,正则表达式的匹配
[*]根本要素

[*][[]]两个符号,左右都要有空格分隔
[*]内部操作符与操作变量之间要有空格,如:[[ "a" = "b" ]]
[*]字符串比力中,可以直接利用> <,无需转义
[*][[]]中字符串或者${}变量只管利用""双引号括住

[*]如未利用""双引号括住的话,会举行模式和元字符匹配

[*][[]]内部可以利用&& ||举行逻辑运算
[*][[]]是bash的keyword
[*][[]]其他用法都和[]一样

4.现实上手



[*]测试逻辑判断#!/bin/bash

read -p "Pls input a char:> " var1

[ "${var1}" -eq 1 ] && {
    echo ${var1}
    exit 0
}

[ "$var1" -eq 2 ] && {
    echo $var1
    exit 0
}

[ "$var1" -ne "1" -a "$var1" -ne "2" ] && {
    echo "Script Error"
    exit 1
}

[*]模拟安装脚本#!/bin/bash

path=/scripts

[ ! -d "$path" ] && mkdir -p scripts

cat << END
        1.
        2.
        3.
END

read -p "Pls input your choice:> " num

# 判断输入是否合法
[[ ! $num =~ ]] && {
        echo "The num you input must be in {1|2|3}"
        echo "Input Error"
        exit 1
}

[ $num -eq 1 ] && {
        echo "start installing lamp...waiting..."
        sleep 2

        # 如果该脚本没权限
        [ ! -x "$path/lamp.sh" ] || {
                echo "The file does not exit or can't be exec"
                exit 2
        }

        # 安装脚本
        source ${path}/lamp.sh
        exit $?
}

[ $num -eq 2 ] && {
        echo "start installing lnmp...waiting..."
        sleep 2
        [ ! -x "$path/lnmp.sh" ] || {
                echo "The file does not exit or can't be exec"
                exit 3
        }
        source ${path}/lnmp.sh
        exit $?
}

[ $num -eq 3 ] && {
        echo "Bye~"
        exit 4
}

3.循环

1.for



[*]语法:for var in list
do
        commands
done

[*]支持C语言风格for (( i=1;i<=10;i++ ))
do
        echo "The next number is $i"
done

2.while



[*] 语法:此处的test command和if-else语句格式一样,可以利用任何的bash命令

[*]注意:while的test command的退出状态码,必须随着循环⾥的命令改变,否则状态码如果不变化,循环会不停⽌的继续下去while test command
do
        commands
done


[*] while命令可以写入多个测试命令

[*]只有最后一个测试命令的退出状态码会被决定是否退出循环
[*]注意换行,多个测试命令要单独的出如今每一行var1=10
while echo $var1
        [ $var1 -ge 0 ]
do
        echo "This is inside the loop"
        var1=$[ $var1 -1 ]
done


3.until命令



[*]until和while是相反的语意,until命令要求你指定⼀个返回⾮零退出码的测试命令

[*]只有退出状态码不是0,bash才会执⾏循环的命令

[*]语法:until test commands
do
        other commands
done

[*]until也⽀持多个测试命令,只有最后⼀个决定bash是否执⾏其他命令until echo $var1
        [ $var1 -eq 0 ]
do
        echo "Inside the loop:$var1"
        var1=$[ $var1 - 25 ]
done

4.控制循环

1.break



[*]作用:强制退出任意类型的循环

[*]跳出多个循环时,break会主动停止所在的最内存循环

[*]停止外层循环:n体现跳出的循环层级,默认是1,下一层就是2break n

2.continue



[*]作用:跳过某次循环,直接去本次循环的判断部分
5.处置惩罚循环的输出



[*]在shell脚本⾥,循环输出后的结果,可以进⾏输出重定向for (( a = 1;a<10;a++ ))
do
        echo "The number is $a"
done > test.txt
echo "Finished"


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: [Linux][Shell][Shell逻辑控制]详细教学