运算符解释
- -eq :等于则为真
- -ne:不等于则为真
- -gt :大于则为真
- -lt :小于则为真
- -ge :大于或等于则为真
- -le :小于或等于则为真
注意:可以使用man test命令查看详细信息。
test
命令仅用来做判断,返回结果为1和0 。
[root@bogon shell-05]# test 1 -eq 1;echo $?
0
[root@bogon shell-05]# test 1 -gt 1;echo $?
1
[root@bogon shell-05]# test 1 -ge 1;echo $?
0
[root@bogon shell-05]# test 1 -le 1;echo $?
0
[root@bogon shell-05]# test 1 -lt 1;echo $?
1
[root@bogon shell-05]# test 1 -ne 1;echo $?
1
[root@bogon shell-05]# test 1 -ne 2;echo $?
0
[root@bogon shell-05]#
------------浮点数比较,小数点后一位,放大十倍,小数点后两位,放大一百倍-------------
echo "1.5*10"| bc | cut -d '.' -f1
test `echo "1.5*10" | bc | cut -d '.' -f1` -eq 20;echo $?
test `echo "1.5*10" | bc | cut -d '.' -f1` -eq $((2*10));echo $?
例子:
[root@arm-00 test]$ bash float.sh
1
[root@arm-00 test]$ cat float.sh
#!/bin/bash
NUM1=`echo "1.5*10"|bc|cut -d "." -f1`
NUM2=$((2*10))
test $NUM1 -gt $NUM2;echo $?
[root@arm-00 test]$ bash -x float.sh
++ echo '1.5*10'
++ bc
++ cut -d . -f1
+ NUM1=15
+ NUM2=20
+ test 15 -gt 20
+ echo 1
1
[root@arm-00 test]$
bash -x 文件名
-x 查看debug流程。
运算符解释,注意字符串一定别忘啦使用引号引起来。
- == :相等则为真
- != :不相等则为真
- =~ :前边变量包含后边变量则为真。
- -n :检查字符串的长度是否大于0
- -z :检查字符串的长度是否为0
test $USER == 'root';echo $?
if [ $var1 == $var2 ]
test $USER != 'root';echo $?
if [ $var1 != $var2 ]
#test 不可行,可以用其他方式验证。
[[ $var1 =~ $var2 ]] && echo $?
------执行结果------
[root@x86-03 opt]# test $USER == 'root';echo $?
0
[root@x86-03 opt]# test $USER != 'root';echo $?
1
[root@x86-03 opt]# test $USER !~ 'root';echo $?
bash: !~: event not found
[root@x86-03 opt]# test $USER \!\~ 'root';echo $?
bash: test: !~:需要二元表达式
2
[root@x86-03 opt]# [[ $USER =~ "root" ]] && echo $?
0
[root@x86-03 opt]#
字符串测试运算
参数 | 说明 |
---|---|
-z 字符串 | 字符串的长度为零则为真 |
-n 字符串 | 字符串的长度不为零则为真 |
test -z "$abc";echo $?
if [ -z $var1 ]
test -n "$abc";echo $?
if [ -n $var1 ]
------执行结果------
[root@x86-03 opt]# test -z "$abc";echo $?
0
[root@x86-03 opt]# test -n "$abc";echo $?
1
[root@x86-03 opt]#
=
:赋值运算符
试例: a=10 name=‘baishu’
逻辑与运算 : &&
逻辑或运算 : ||
逻辑非运算 : !逻辑运算注意事项:
逻辑与 或 运算都需要两个或以上条件,逻辑非运算只能一个条件。
口诀:
逻辑与运算 真真为真,真假为假,假假为假
逻辑或运算 真真为真,真假为真,假假为假
逻辑非运算 非假为真,非真为假
if [ 1 -eq 1 ] && [ 1 -lt 2 ];then echo "yes";else echo "no";fi
文件比较与检查
- -d :检查文件是否存在且为目录
- -e :检查文件是否存在(判断文件和目录)
- -f :检查文件是否存在且为文件
- -r :检查文件是否存在且可读
- -s:检查文件是否存在且不为空
- -w:检查文件是否存在且可写
- -x :检查文件是否存在且可执行
- -O :检查文件是否存在并且被当前用户拥有
- -G :检查文件是否存在并且默认组为当前用户
file1 -nt file2 :检查file1是否比file2新
file1 -ot file2 :检查file1是否比file2旧
注意:root是超级管理员,有些权限对root没有限制
[tonghuan@arm-00 test]$ ln float.sh xxx
[tonghuan@arm-00 test]$ ls
array.sh float.sh xxx
[tonghuan@arm-00 test]$ ll
total 12
-rw-rw-r--. 1 tonghuan tonghuan 105 Mar 7 15:48 array.sh
-rw-rw-r--. 2 tonghuan tonghuan 97 Mar 15 10:27 float.sh
-rw-rw-r--. 2 tonghuan tonghuan 97 Mar 15 10:27 xxx
[tonghuan@arm-00 test]$ ls -il float.sh xxx
1623254316 -rw-rw-r--. 2 tonghuan tonghuan 97 Mar 15 10:27 float.sh
1623254316 -rw-rw-r--. 2 tonghuan tonghuan 97 Mar 15 10:27 xxx
[tonghuan@arm-00 test]$ test float.sh -ef xxx
[tonghuan@arm-00 test]$ test float.sh -ef xxx;echo $?
0
[tonghuan@arm-00 test]$ test float.sh -ef array.sh ;echo $?
1
[tonghuan@arm-00 test]$ test float.sh -nt xxx
[tonghuan@arm-00 test]$ test float.sh -nt xxx ;echo $?
1
[tonghuan@arm-00 test]$ test float.sh -ot xxx ;echo $?
1
[tonghuan@arm-00 test]$ test float.sh -ot array.sh ;echo $?
1
[tonghuan@arm-00 test]$ test float.sh -nt array.sh ;echo $?
0
[tonghuan@arm-00 test]$ stat float.sh
File: ‘float.sh’
Size: 97 Blocks: 8 IO Block: 65536 regular file
Device: fd05h/64773d Inode: 1623254316 Links: 2
Access: (0664/-rw-rw-r--) Uid: ( 1005/tonghuan) Gid: ( 1006/tonghuan)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2022-03-15 10:27:34.647477663 +0800
Modify: 2022-03-15 10:27:29.977436317 +0800
Change: 2022-03-15 11:36:20.784000638 +0800
Birth: -
[tonghuan@arm-00 test]$ ls
array.sh float.sh xxx
[tonghuan@arm-00 test]$ echo -d ./tmp
-d ./tmp
[tonghuan@arm-00 test]$ ls
array.sh float.sh xxx
[tonghuan@arm-00 test]$ test -d ./tmp;echo $?
1
[tonghuan@arm-00 test]$ test -d ../test/;echo $?
0
[tonghuan@arm-00 test]$ test -e float.sh
[tonghuan@arm-00 test]$ test -e float.sh ;echo $?
0
[tonghuan@arm-00 test]$ echo -f float.sh ;echo $?
-f float.sh
0
[tonghuan@arm-00 test]$ test -f float.sh ;echo $?
0
[tonghuan@arm-00 test]$ test -f test;echo $?
1
[tonghuan@arm-00 test]$ test -r float.sh
[tonghuan@arm-00 test]$ test -r float.sh ;echo $?
0
[tonghuan@arm-00 test]$ test -rwx float.sh ;echo $?
-bash: test: -rwx: unary operator expected
2
[tonghuan@arm-00 test]$ test -rw float.sh ;echo $?
-bash: test: -rw: unary operator expected
2
[tonghuan@arm-00 test]$ test -r float.sh ;echo $?
0
[tonghuan@arm-00 test]$ test -r float.sh ;echo $?
0
[tonghuan@arm-00 test]$ test -O float.sh ;echo $?
0
[tonghuan@arm-00 test]$ test -G float.sh ;echo $?
0
[tonghuan@arm-00 test]$ sudo su root
[sudo] password for tonghuan:
[root@arm-00 test]# test -G float.sh ;echo $?
1
[root@arm-00 test]# test -O float.sh ;echo $?
1
[root@arm-00 test]#
适用范围:只需要一步判断,条件返回真干什么或者条件返回假干什么。
if [ condition ] #condition 值为true or false
then
command
fi
该语句翻译成汉语大意如下:
假如 条件为真
那么
执行command代码块
结束
案例1:通过一段代码来演示一下,判断当前用户是不是root用户,如果不是那么返回“ERROR:need to be root so that!”
root@DESKTOP-4JHP1VV:/opt# vim if-user.sh
root@DESKTOP-4JHP1VV:/opt# sh if-user.sh
root@DESKTOP-4JHP1VV:/opt# exit
exit
zs@DESKTOP-4JHP1VV:~$ ls
zs@DESKTOP-4JHP1VV:~$ cd /opt/
zs@DESKTOP-4JHP1VV:/opt$ ls
file.sh if-user.sh
zs@DESKTOP-4JHP1VV:/opt$ sh if-user.sh
ERROR:need to be root so that!
zs@DESKTOP-4JHP1VV:/opt$ cat if-user.sh
#!/bin/bash
if [ $(whoami) != 'root' ]
then
echo "ERROR:need to be root so that!"
exit 1;
fi
zs@DESKTOP-4JHP1VV:/opt$
案例2:判断文件目录是否存在?
root@DESKTOP-4JHP1VV:/opt# sh file.sh
mkdir: created directory '/tmp/abc'
123
create /tmp/abc ok!
root@DESKTOP-4JHP1VV:/opt# sh file.sh
root@DESKTOP-4JHP1VV:/opt# ls /tmp/abc/
root@DESKTOP-4JHP1VV:/opt# ls /tmp/
abc pulse-PKdhtXMmr18n
root@DESKTOP-4JHP1VV:/opt# cat file.sh
#!/bin/bash
if [ ! -d /tmp/abc ]
then
mkdir -v /tmp/abc
echo "123"
echo "create /tmp/abc ok!"
fi
root@DESKTOP-4JHP1VV:/opt#
适用范围:两步判断,条件为真做什么,条件为假做什么。
if [ condition ]
then
command
else
command
fi
该语句翻译成汉语大意如下:
假如条件为真
那么
执行command1代码块
否则
执行command2代码块
结束
通过一段代码演示一下,判断当前登录用户是管理员还是普通用户,如果是管理员输出为“hey admin”如果是普通用户输出“hey guest”
#!/bin/bash
if [ $(whoami) != 'root' ]
then
echo "hey guest"
else
echo "hey admin"
fi
-------------------执行结果------------------
root@DESKTOP-4JHP1VV:/opt# su - th -c "bash /opt/if-user.sh"
hey guest
root@DESKTOP-4JHP1VV:/opt# exit
exit
th@DESKTOP-4JHP1VV:/opt$ sudo su - root -c "bash /opt/if-user.sh"
hey admin
th@DESKTOP-4JHP1VV:/opt$
适用范围:多于两个以上的判断结果,也就是多于一个的判断条件
if [ condition 1 ]
then
command 1
elif [ condition 2 ]
then
command 2
......
else
command x
fi
该语句翻译成汉语大意如下:
假如 条件1 为真
那么
执行代码块command 1
假如 条件2 为真
那么
执行代码块command 2
以此类推的N个条件及对应的执行代码块
否则 #【以上所有条件中没有一个满足的】
执行代码块 x
结束
root@DESKTOP-4JHP1VV:/opt# cat if-elif.sh
#!/bin/bash
#判断两个整数的关系,使用嵌套if语句
if [ $1 -eq $2 ]
then
echo "$1 = $2"
else
if [ $1 -gt $2 ]
then
echo "$1 > $2"
else
echo "$1 < $2"
fi
fi
root@DESKTOP-4JHP1VV:/opt# sh if-elif.sh 12 13
12 < 13
root@DESKTOP-4JHP1VV:/opt# sh if-elif.sh 12 11
12 > 11
root@DESKTOP-4JHP1VV:/opt# sh if-elif.sh 12 12
12 = 12
-----------------------------------------------------------
root@DESKTOP-4JHP1VV:/opt# cat if-elif.sh
#!/bin/bash
#判断两个整数的关系,使用if-elif
if [ $1 -gt $2 ]
then
echo "$1 > $2"
elif [ $1 -eq $2 ]
then
echo "$1 = $2"
else
echo "$1 < $2"
fi
root@DESKTOP-4JHP1VV:/opt# sh if-elif.sh 12 13
12 < 13
root@DESKTOP-4JHP1VV:/opt# sh if-elif.sh 12 11
12 > 11
root@DESKTOP-4JHP1VV:/opt# sh if-elif.sh 12 12
12 = 12
root@DESKTOP-4JHP1VV:/opt#
双小括号(())
的作用:可以用来做运算
root@DESKTOP-4JHP1VV:/opt# cat if-1.sh
#!/bin/bash
if (( 100%3+1>10 ));then
echo "yes"
else
echo "no"
fi
#结合下一节的for一起使用
for i in r1 rr2 cc cc3 vv
do
if [[ $i == r* ]];then
echo $i
fi
done
root@DESKTOP-4JHP1VV:/opt# sh if-1.sh
no
r1
rr2
root@DESKTOP-4JHP1VV:/opt#
案例:
1、判断一个机器是否存活;能ping通就算存活。
2、判断服务器上的某个服务是否开启
3、判断某年是否为闰年
4、写一个Nginx安装脚本,加入判断,当上一步执行成功在执行下一步,否则推出脚本。
5、写一个备份脚本,将A机器当天修改过的文件收集到/cache目录,打包并发送到B机器的/opt/backup目录下,通过MD5值判断是否B机器上的备份的完整性。
思路:
下载Nginx包
假如下载成功
那么
解压
进入目录
假如 编译成功
那么
安装
否则
报错 安装失败
安装结束
否则
报错 编译失败
退出脚本
编译结束
否则
报错 配置错误
退出脚本
配置结束
否则
报错 下载失败
退出脚本
下载结束
其if的高端用法在于yum_right变量,[]内的yum_right如果在做了声明,不管赋值为多少,结果均为真,相反未声明为假。
这种写法不等同于[ $yum_right -eq 3 ],前者做是否声明判断真假,后者变量关系判断真假。
案例:执行判断某安装包是否安装执行成功,如果未安装成功则打印’yum cannot install ’
for i in wget gcc
do
if [ ! `rpm -qa | grep ^$i-[0-9].` ] ; then
yum install -y $i
[ $? -ne 0 ] && echo 'yum cannot install '$i && yum_right=3
fi
done
[ $yum_right ] && exit 3
很多人把for循环叫做条件循环,或者for i in 。
其实前者说的就是for的特性,for循环的次数和给予的条件是成正比的,你给他5次,他的循环5次;
后者说的是for的语法。
for的语法一
for var in value1 value2 ......
do
command
done
接下来看段代码,循环输出1-9数字
#1、for直接赋值
#for var in 1 2 3 4 5 6 7 8 9
#2、使用命令赋值
#for var in `seq 1 9`
root@DESKTOP-4JHP1VV:/opt# cat for-1.sh
#!/bin/bash
for i in `seq 1 9`
do
echo $i
done
root@DESKTOP-4JHP1VV:/opt# sh for-1.sh
1
2
3
4
5
6
7
8
9
root@DESKTOP-4JHP1VV:/opt#
#3、赋值是一个字符串
#for var in baidu\'s is cool, sum\'s is hot.
root@DESKTOP-4JHP1VV:/opt# cat for-5.sh
#!/bin/bash
for var in ice\'s is cool,sum\'s is hot.
do
echo "word:$var"
done
root@DESKTOP-4JHP1VV:/opt# bash for-5.sh
word:ice's
word:is
word:cool,sum's
word:is
word:hot.
root@DESKTOP-4JHP1VV:/opt#
for语法二
C 式的for命令
for (( 变量;条件;自增减运算 ))
do
代码块
done
来段代码理解一下,还是输出1-9
注意:此处报错是因为使用的解释器sh不支持这种C语言格式的for循环写法。
将默认shell更改为bash。bash支持C语言格式的for循环。
root@DESKTOP-4JHP1VV:/opt# cat for-2.sh
#!/bin/bash
for (( i=1;i<10;i++ ))
do
echo $i
done
root@DESKTOP-4JHP1VV:/opt# sh for-2.sh
for-2.sh: 2: for-2.sh: Syntax error: Bad for loop variable
root@DESKTOP-4JHP1VV:/opt# bash for-2.sh
1
2
3
4
5
6
7
8
9
root@DESKTOP-4JHP1VV:/opt#
C 式for循环使用多个变量
root@DESKTOP-4JHP1VV:/opt# cat for-3.sh
#!/bin/bash
for ((a=0,b=9;a<10;a++,b--))
do
echo $a $b
done
root@DESKTOP-4JHP1VV:/opt# bash for-3.sh
0 9
1 8
2 7
3 6
4 5
5 4
6 3
7 2
8 1
9 0
root@DESKTOP-4JHP1VV:/opt#
for无限循环 使用((;;))
条件可以实现无限循环
案例:编写一个倒计时。
root@DESKTOP-4JHP1VV:/opt# cat for-4.sh
#!/bin/bash
for ((;;))
do
echo "hehe"
sleep 2s
done
root@DESKTOP-4JHP1VV:/opt# bash for-4.sh
hehe
hehe
hehe
hehe
^C
root@DESKTOP-4JHP1VV:/opt#
循环的优点:
1)节省内存 10M脚本 1M脚本 比较哪个更节省内存,完成同一个任务。
2)结构更清晰
3)节省时间成本
sleep N 脚本执行到该步休眠N秒
先看段代码:
root@DESKTOP-4JHP1VV:/opt# cat sleep.sh
#!/bin/bash
echo -n "倒计时:"
for i in `seq 9 -1 1`
do
echo -n -e "\b$i"
sleep 1
done
echo
root@DESKTOP-4JHP1VV:/opt# sh sleep.sh
倒计时:5
root@DESKTOP-4JHP1VV:/opt# cat for-sleep.sh
#!/bin/bash
#监控主机存活的脚本,5秒中监控一次
for ((;;))
do
ping -c1 $1 &>/dev/null
if [ $? -eq 0 ]
then
echo -e "`date +"%F %H:%M:%S"` : $1 is \033[32mUP\033[0m"
else
echo -e "`date +"%F %H:%m:%S"` : $1 is \033[31mDown\033[0m"
fi
#脚本节奏控制 生产环境建议1分钟及以上
sleep 5s
done
root@DESKTOP-4JHP1VV:/opt# sh for-sleep.sh x86-01.foxitjj.net
2022-04-27 17:03:20 : x86-01.foxitjj.net is UP
2022-04-27 17:03:25 : x86-01.foxitjj.net is UP
^C
root@DESKTOP-4JHP1VV:/opt# sh for-sleep.sh x86-01.foxitjj.net0
2022-04-27 17:04:30 : x86-01.foxitjj.net0 is Down
2022-04-27 17:04:35 : x86-01.foxitjj.net0 is Down
^C
root@DESKTOP-4JHP1VV:/opt#
continue跳过循环中的某次循环
#!/bin/bash
#要求输出: 12346789
for ((i=1;i<10;i++))
do
if [ $i -eq 5 ];then
#跳过本次循环
continue
fi
done
break跳出循环继续执行后续代码
#!/bin/bash
#要求用户输入一个字母,当输入Q的时候退出
for ((;;))
do
read -p "char:" ch
if [ $ch == "Q" ]
then
#终止本循环
break
#如果循环多层嵌套,循环从里往外排序0-N
#如果想跳出某层循环,break N
else
echo "你输入的字符是:$ch"
fi
done
#!/bin/bash
#break,跳出外循环
for ((i=1;i<100;i++))
do
echo "#loop $i"
for ((;;))
do
echo "haha"
break 2
done
sleep 3
done
------------执行结果--------------
th@123:~/data$ cat for-break.sh
#!/bin/bash
#break
for ((i=1;i<100;i++))
do
echo "#loop $i"
for ((;;))
do
echo "haha"
break
done
sleep 3
done
th@123:~/data$ bash for-break.sh
#loop 1
haha
#loop 2
haha
#loop 3
haha
#loop 4
haha
#loop 5
haha
#loop 6
haha
#loop 7
haha
#loop 8
haha
#loop 9
haha
^C
th@123:~/data$ vim for-break.sh
th@123:~/data$ cat for-break.sh
#!/bin/bash
#break
for ((i=1;i<100;i++))
do
echo "#loop $i"
for ((;;))
do
echo "haha"
break 2
done
sleep 3
done
th@123:~/data$ bash for-break.sh
#loop 1
haha
th@123:~/data$
案例:
1、扫描一下你的网段中那些节机器是存活的。
2、手动写一个同步拉脚本,要求B机器每隔10分钟把A机器中的/opt/cache/下的内容拉取到B机器的/opt/cache,并做完整性验证。
3、新建user01-user20用户,要求密码是随机6位数,密码取值范围a-zA-Z0-9,要求密码不能是单一的数字或者小写或者大写字母。
4、写一个mysql分库备份的脚本。
5、写一个猜数字脚本,数字范围是1-100,定制计数器,每次猜完都要告诉用户猜大或者猜小,如果猜对了就跳出脚本并输出计数器的值。
6、为DNS写一个自动判断WEB分析的脚本
公司DNS将域名www.ayitula.com解析到了两个WEB服务器,以实现DNS负载均衡。但是当某个WEB服务器出现故障,那么DNS依然会将自己解析到宕机WEB,造成不能正常访问,故要求写一个运行在DNS的检查脚本,当发现哪台宕机后,自己修改DNS的解析记录,关闭对其的解析。当WEB恢复,DNS在打开对其的解析,恢复解析。
7、写一个九九乘法表。
while在shell中也是负责循环的语句,和for一样。因为功能一样,在学习工作中的脚本遇到循环的时候到底该使用for还是while呢?我个人认为,既然知道循环次数就可以用for,比如说一天需要循环24次;如果不知道代码要循环多少次,那就用while,比如我们作业中要求写的猜数字,每个人猜对的次数都是不能固定的,也是未知的。所以这样的循环我就建议大家使用while了。
while [ condition ] #注意,条件为真while才会循环,条件为假,while停止循环。
do
command
done
1)使用while遍历文件内容。
root@DESKTOP-4JHP1VV:/home/123# bash while-base.sh
NUM:3
大于
大于
大于
大于
^C
root@DESKTOP-4JHP1VV:/home/123# cat while-base.sh
#!/bin/bash
#while基础语法学习
#条件可以是我们学习中的五种运算中的任意一种
#数学比较 字符串比较 文件类型 逻辑运算 赋值运算
read -p "NUM:" num1
while [ $num1 -gt 0 ]
do
echo "大于"
sleep 3
done
root@DESKTOP-4JHP1VV:/home/123# bash -x while-base.sh
+ read -p NUM: num1
NUM:12
+ '[' 12 -gt 0 ']'
+ echo 大于
大于
+ sleep 3
+ '[' 12 -gt 0 ']'
+ echo 大于
大于
+ sleep 3
+ '[' 12 -gt 0 ']'
+ echo 大于
大于
+ sleep 3
^C
root@DESKTOP-4JHP1VV:/home/123#
---------------------------------------------------
root@DESKTOP-4JHP1VV:/home/123# bash while-base.sh
login: 1
login: 12
login: ae
login: wer怕【
login: root
root@DESKTOP-4JHP1VV:/home/123# bash -x while-base.sh
+ read -p 'login: ' account
login: eooo
+ '[' eooo '!=' root ']'
+ read -p 'login: ' account
login: 132
+ '[' 132 '!=' root ']'
+ read -p 'login: ' account
login: root
+ '[' root '!=' root ']'
root@DESKTOP-4JHP1VV:/home/123# cat while-base.sh
#!/bin/bash
#while基础语法学习
#条件可以是我们学习中的五种运算中的任意一种
#数学比较 字符串比较 文件类型 逻辑运算 赋值运算
#read -p "NUM:" num1
#while [ $num1 -gt 0 ]
#do
# echo "大于"
# sleep 3
#done
read -p "login: " account
while [ $account != 'root' ]
do
read -p "login: " account
done
root@DESKTOP-4JHP1VV:/home/123#
2)案例:丈母娘选女婿的标准
123@DESKTOP-4JHP1VV:~$ bash -x while-test.sh
+ read -p 'money: ' money
money: 123
+ read -p 'car: ' car
car: 123
+ read -p 'house: ' house
house: 123
+ '[' 123 -lt 100000 ']'
+ echo -e '\033[31m no,next!\033[0m'
no,next!
+ read -p 'money: ' money
money: 123123
+ read -p 'car: ' car
car: 123
+ read -p 'house: ' house
house: 123
+ '[' 123123 -lt 100000 ']'
+ '[' 123 -lt 1 ']'
+ '[' 123 -lt 1 ']'
+ echo -e '\033[32m yes\033[0m'
yes
123@DESKTOP-4JHP1VV:~$ cat while-test.sh
#!/bin/bash
#丈母娘选女婿的标准
#1)姑娘带回来第一个男朋友
read -p "money: " money
read -p "car: " car
read -p "house: " house
#2)第一个男朋友筛选条件,进入循环 ,开始选择模式
while [ $money -lt 100000 ] || [ $car -lt 1 ] || [ $house -lt 1 ]
do
echo -e "\033[31m no,next!\033[0m"
read -p "money: " money
read -p "car: " car
read -p "house: " house
done
echo -e "\033[32m yes\033[0m"
123@DESKTOP-4JHP1VV:~$
1)打印1-9数字
123@DESKTOP-4JHP1VV:~$ bash while-other.sh
1
2
3
4
5
6
7
8
9
123@DESKTOP-4JHP1VV:~$ cat while-other.sh
#!/bin/bash
#1、嵌套 if for while
#2、循环控制sleep break continue
i=1
while [ $i -lt 10 ]
do
echo $i
i=$((i+1))
done
th@DESKTOP-4JHP1VV:~$
2)打印1-9,输出到5的时候跳出循环
123@DESKTOP-4JHP1VV:~$ cat while-other.sh
#!/bin/bash
#1、嵌套 if for while
#2、循环控制sleep break continue
i=1
while [ $i -lt 10 ]
do
echo $i
if [ $i -eq 5 ];then
break
fi
i=$((i+1))
done
123@DESKTOP-4JHP1VV:~$ bash while-other.sh
1
2
3
4
5
123@DESKTOP-4JHP1VV:~$
3)打印1-9,当数值为5时跳过当前循环,输出到8的时候跳出循环。
root@DESKTOP-4JHP1VV:/home/123# bash while-other.sh
1
2
3
4
6
7
root@DESKTOP-4JHP1VV:/home/123# cat while-other.sh
#!/bin/bash
#1、嵌套 if for while
#2、循环控制sleep break continue
#打印1-9,当数值为5时跳过当前循环
i=0
while [ $i -lt 10 ]
do
i=$((i+1))
if [ $i -eq 5 ];then
continue
fi
#输出到8的时候跳出循环
if [ $i -eq 8 ];then
break
fi
echo $i
done
root@DESKTOP-4JHP1VV:/home/123#
4)99乘法表
root@DESKTOP-4JHP1VV:/home/123# bash while-other.sh
1 * 1 = 1
1 * 2 = 2 2 * 2 = 4
1 * 3 = 3 2 * 3 = 6 3 * 3 = 9
1 * 4 = 4 2 * 4 = 8 3 * 4 = 12 4 * 4 = 16
1 * 5 = 5 2 * 5 = 10 3 * 5 = 15 4 * 5 = 20 5 * 5 = 25
1 * 6 = 6 2 * 6 = 12 3 * 6 = 18 4 * 6 = 24 5 * 6 = 30 6 * 6 = 36
1 * 7 = 7 2 * 7 = 14 3 * 7 = 21 4 * 7 = 28 5 * 7 = 35 6 * 7 = 42 7 * 7 = 49
1 * 8 = 8 2 * 8 = 16 3 * 8 = 24 4 * 8 = 32 5 * 8 = 40 6 * 8 = 48 7 * 8 = 56 8 * 8 = 64
1 * 9 = 9 2 * 9 = 18 3 * 9 = 27 4 * 9 = 36 5 * 9 = 45 6 * 9 = 54 7 * 9 = 63 8 * 9 = 72 9 * 9 = 81
root@DESKTOP-4JHP1VV:/home/123# cat while-other.sh
#!/bin/bash
#1、嵌套 if for while
#2、循环控制sleep break continue
a1(){
#99乘法表
#1*1=1
#1*2=2 2*2=4
#1*3=3 2*3=6 3*3=9
for ((n=1;n<10;n++))
do
for ((m=1;m<=n;m++))
do
echo -n -e "$m * $n =$((n*m))\t"
done
echo
done
}
n=1
while [ $n -lt 10 ]
do
for ((m=1;m<=$n;m++))
do
echo -n -e "$m * $n = $((m*n))\t"
done
echo
n=$((n+1))
done
root@DESKTOP-4JHP1VV:/home/123#
5)使用while读出文件中的列,IFS只当默认的列分割符
root@DESKTOP-4JHP1VV:/home/123# bash while-2.sh
root x 0
daemon x 1
bin x 2
sys x 3
sync x 4
games x 5
man x 6
lp x 7
mail x 8
news x 9
uucp x 10
proxy x 13
www-data x 33
backup x 34
list x 38
irc x 39
gnats x 41
nobody x 65534
systemd-network x 100
systemd-resolve x 101
syslog x 102
messagebus x 103
_apt x 104
lxd x 105
uuidd x 106
dnsmasq x 107
landscape x 108
sshd x 109
pollinate x 110
th x 1000
root@DESKTOP-4JHP1VV:/home/123# cat while-2.sh
#!/bin/bash
IFS=$":"
while read f1 f2 f3 f4 f5
do
echo "$f1 $f2 $f3"
done < /etc/passwd
root@DESKTOP-4JHP1VV:/home/123#
until和while正好相反,until是条件为假开始执行,条件为真停止执行。
until [ condition ] #注意,条件为假until才会循环,条件为真,停止循环。
do
command
done
案例1:
#!/bin/bash
init_num=10
until [ $init_num -gt 20 ]
do
echo $init_num
init_num=$((init_num+1))
done
#输出
root@DESKTOP-4JHP1VV:/home/123# bash until-1.sh
10
11
12
13
14
15
16
17
18
19
20
root@DESKTOP-4JHP1VV:/home/123# cat until-1.sh
#!/bin/bash
init_num=10
until [ $init_num -gt 20 ]
do
echo $init_num
init_num=$((init_num+1))
done
root@DESKTOP-4JHP1VV:/home/123#
案例2:
root@DESKTOP-4JHP1VV:/home/th# bash until-1.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
root@DESKTOP-4JHP1VV:/home/th# cat until-1.sh
#!/bin/bash
num=1
#while 1-9
while [ $num -lt 10 ]
do
echo $num
num=$((num+1))
until [ $num -lt 10 ]
do
echo $num
if [ $num -eq 20 ];then
break
fi
num=$((num+1))
done
done
root@DESKTOP-4JHP1VV:/home/th#
在生产环境中,我们总会遇到一个问题需要根据不同的状况来执行不同的预案,那么我们要处理这样的问题,就要首先根据可能出现的情况写出对应的预案根据出现的情况来加载不同的预案。
特点:根据给与的不同条件执行不同的代码块
- 比如:石头、剪刀、布游戏。
第一次出的是:石头
第二次出的是:剪刀
第三次出的是:布
。。。- 在举一个计算机的例子:
内存使用率低于80%,脚本输出:绿色字体的Memory use xx%
内存使用率大于80%小于90%,脚本输出:黄色字体的Memory use xx%
内存使用率大于90%,脚本输出:红色字体的Memory use xx%
case 变量 in
条件1)
执行代码块1
;;
条件2)
执行代码块2
;;
......
esac
注意:每个代码块执行完毕要以;;结尾代表结束,case结尾要以倒过来写的esac来结尾。
案例说明
#!/bin/bash
read -p "NUM: " N
case $N in
1)
echo "hhhhh"
;;
2)
echo "hehe"
;;
3)
echo "heihei"
;;
*)
echo bye
;;
esac
-----------------执行结果--------------------
root@DESKTOP-4JHP1VV:/home/123# sh case-1.sh
NUM: 1
hhhh
root@DESKTOP-4JHP1VV:/home/123# sh case-1.sh
NUM: 2
hehe
root@DESKTOP-4JHP1VV:/home/123# sh case-1.sh
NUM: 3
heihei
root@DESKTOP-4JHP1VV:/home/123# sh case-1.sh
NUM: 4
bye
root@DESKTOP-4JHP1VV:/home/123# cat case-1.sh
#!/bin/bash
read -p "NUM: " N
case $N in
1)
echo "hhhh"
;;
2)
echo "hehe"
;;
3)
echo "heihei"
;;
*)
echo bye
esac
root@DESKTOP-4JHP1VV:/home/123#
特殊参数
1、$*
:代表所有参数,其间隔为IFS内定参数的第一个字元
2、$@
:与*号类同。不同之处在于不参照IFS。
3、$#
:代表参数数量。
4、$
:执行上一个指令的返回值
5、$-
:最近执行的foreground pipeline的选项参数。
6、$$
:本身的Process ID
7、$
:执行上一个北京指令的PID
8、$_
:显示出最后一个执行的命令
9、$N
:shell的第几个外传参数
案例:
#!/bin/bash
echo "脚本的名字是:$0"
echo "脚本的参数是:$*"
echo "传参数量:$#"
echo "脚本执行进程号:$$"
echo "最后执行命令是:$_"
echo "第二个参数是:$2"
-------------------执行结果--------------------
root@DESKTOP-4JHP1VV:/home/123# bash shell_variable.sh
脚本的名字是:shell_variable.sh
脚本的参数是:
传参数量:0
脚本执行进程号:120
最后执行命令是:脚本执行进程号:120
第二个参数是:
root@DESKTOP-4JHP1VV:/home/123# bash shell_variable.sh 1
脚本的名字是:shell_variable.sh
脚本的参数是:1
传参数量:1
脚本执行进程号:121
最后执行命令是:脚本执行进程号:121
第二个参数是:
root@DESKTOP-4JHP1VV:/home/123# bash shell_variable.sh 13 23
脚本的名字是:shell_variable.sh
脚本的参数是:13 23
传参数量:2
脚本执行进程号:122
最后执行命令是:脚本执行进程号:122
第二个参数是:23
root@DESKTOP-4JHP1VV:/home/123# cat shell_variable.sh
#!/bin/bash
echo "脚本的名字是:$0"
echo "脚本的参数是:$*"
echo "传参数量:$#"
echo "脚本执行进程号:$$"
echo "最后执行命令是:$_"
echo "第二个参数是:$2"
root@DESKTOP-4JHP1VV:/home/123#