[Linux][Shell][Shell逻辑控制]详细讲解
DieSnowK 2024-07-28 09:07:02 阅读 53
目录
1.if 判断1.if-then2.if-then-else3.elif4.case5.实际上手
2.条件测试0.事前说明1.test 命令2.[]3.双括号1.(())2.[[]]
4.实际上手
3.循环1.for2.while3.until命令4.控制循环1.break2.continue
5.处理循环的输出
1.if 判断
1.if-then
语法:
<code>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 command
then
command
elif 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"code>
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.事前说明
条件测试常用的语法
常用字符串测试操作符
数值比较
逻辑操作符
各命令对照表
1.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 是否为同⼀⽂件,可⽤在硬链接的判定上主要意义在判定,两个⽂件是否均指向同⼀个 |
关于两个整数之间的判定,如:test num1 -eq num2
参数 | 意义 |
---|---|
-eq | 两数相等 |
-ne | 两数不相等 |
-gt | num1 大于num2 |
-lt | num1 小于num2 |
-ge | num1 大于等于num2 |
-le | num1 小于等于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.[install lamp]
2.[install inmp]
3.[exit]
END
read -p "Pls input your choice:> " num
# 判断输入是否合法
[[ ! $num =~ [1-3] ]] && {
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,下一层就是2
break n
2.continue
作用:跳过某次循环,直接去本次循环的判断部分
5.处理循环的输出
在shell脚本⾥,循环输出后的结果,可以进⾏输出重定向
for (( a = 1;a<10;a++ ))
do
echo "The number is $a"
done > test.txt
echo "Finished"
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。