本节内容

1. shell流程控制

2. for语句

3. while语句

4. break和continue语句

5. case语句

6. shell编程高级实战

shell流程控制

流程控制是改变程序运行顺序的指令。linux shell有一套自己的流程控制语句,其中包括条件语句(if),循环语句(for,while),选择语句(case)。下面我将通过例子介绍下,各个语句使用方法

if语句

格式:

格式:if list; then list; [ elif list; then list; ] ... [ else list; ] fi

1.1 单分支

-if 条件表达式; then

-命令

-fi

实例:

#!/bin/bash
N=10
if [ $N -gt 5 ]; then
  echo yes
fi # bash test.sh
yes

1.2 双分支

if 条件表达式; then

  命令

else

命令

fi

实例1:

#!/bin/bash
N=10
if [ $N -lt 5 ]; then
  echo yes
else
echo no
fi
# bash test.sh
no

实例2:判断crond进程是否正在运行

-v: 表示取反

-c: 即count,取代通常的输出,显示行数

#!/bin/bash
NAME=crond
NUM=$(ps aux | grep $NAME | grep -vc grep)
if [ $NUM -eq 1 ]; then
  echo "$NAME running."
else
echo "$NAME is not running!"
fi

实例3:检查主机是否在线

-c:表示发送几次包

-w:表示等待时间。当试图检测不可达主机时此选项很有用。

#!/bin/bash
if ping -c 1 192.168.1.1 &>/dev/null; then
echo "OK."
else
echo "NO!"
fi

if 语句可以直接对命令状态进行判断,就省去了获取$?这一步!

1.3 多分支

if 条件表达式; then

  命令

elif 条件表达式; then

  命令

else 命令

fi

当不确定条件符合哪一个时,就可以把已知条件判断写出来,做相应的处理。

实例1:

$1:表示接受用户输入参数

#!/bin/bash
N=$1
if [ $N -eq 3 ]; then
  echo "eq 3"
elif [ $N -eq 5 ]; then
  echo "eq 5"
elif [ $N -eq 8 ]; then
  echo "eq 8"
else
echo "no"
fi

如果第一个条件符合就不再向下匹配。

shell编程之if语句实战案例

需求:

1. 完成用户输入文件或者目录的自动复制,并可以实现用户指定复制目标位置。

2. 用户体验佳。

#!/bin/bash
read -p "pls enter a file you want to copy:" file
if [ -f $file -o -d $file ];then
read -p "do you want to copy the $file?(y/n)" sure
     confirm=$(echo ${sure} | tr A-Z a-z)
if [ "$confirm" == "y" ];then
read -p "where do you want to copy?" dire
if [ -d $dire ];then
cp -a $file $dire
echo "the $file copied to $dire"
else
echo "the $dire is not exists" exit 1
fi
elif [ "$confirm" == "n" ];then
echo "bye"
else
echo "pls input y or n"
fi
else echo "the $file is not exists"
fi

练习题1:尝试写一个shell简单的计算器,实现加减乘除。

请输入一个数字: 7

请输入运算符:+

请输入第二个数字:7

7+7=14

练习题2:输入一个用户,用脚本判断判断该用户是否存在。

for语句

格式:for name [ [ in [ word ... ] ] ; ] do list ; done

for 变量名 in 取值列表; do

命令

done

或者

for 变量名 in 取值列表

do

命令

done

实例1:

#!/bin/bash
for i in {1..3}; do
echo $i
done # bash test.sh
1
2
3

实例2:计算100以内偶数和

#!/bin/bash
sum=0
for i in `seq 2 2 100`
do
let sum+=$i
done
echo "$sum"

例子3:创建100个用户并设置6位随机密码

[root@ken ~]# cat test9.sh

#!/bin/bash
for i in `seq 10`
do
useradd user$i
pass=`echo $RANDOM | md5sum | cut -c 1-6`
echo “$pass” | passwd --stdin “user$i”
echo -e “账户:user$i\n密码:$pass”>> /root/passwd
done

执行结果:

[root@ken ~]# cat passwd

账户:user1

密码:69a70a

账户:user2

密码:444c02

账户:user3

密码:6b381f

账户:user4

密码:28d8fd

shell编程之for语句实战案例

需求:

1. 批量检查当前教室主机是否在线

#!/bin/bash
. /etc/init.d/functions
ip=192.168.7.
for i in {100..150}
do
if ping -c 1 -w 1 $ip$i &>/dev/null;then
echo -n "$ip$i在线!"
success
echo ""
else
echo -n "$ip$i不在线!"
failure
echo ""
fi
done

练习题1:计算100以内的偶数和

[root@ken ~]# cat test13.sh

#!/bin/bash
sum=0
for i in `seq 2 2 100`
do
let sum+=$i
done
echo “$sum”

执行结果:

[root@ken ~]# bash test13.sh

2550

练习题2:判断/root目录下面的文件类型

#!/bin/bash
for i in `ls /root`
do
type1=`ls -ld $i | cut -c 1`
if [ “$type1” == “-” ];then
echo “$i是普通文件”
elif [ “$type1” == “l” ];then
echo “$i是连接文件”
elif [ “$type1” == “d” ];then
echo “$i是目录”
else
echo “该文件类型无法识别”
fi
done

执行结果:

[root@ken ~]# bash error.sh

error.sh是普通文件

free_mem是普通文件

ken是目录

nohup.out是普通文件

passwd是普通文件

t是普通文件

test10.sh是普通文件

test11.sh是普通文件

test12.sh是普通文件

test13.sh是普通文件

test15.sh是普通文件

test16.sh是普通文件

test18.sh是普通文件

test19.sh是普通文件

while语句

条件为真就进入死循环;条件为假就退出循环

格式:while list; do list; done

while 条件表达式; do

命令

done

实例1:

#!/bin/bash
N=0
while [ $N -lt 5 ]; do
let N++
echo $N
done # bash test.sh
1
2
3
4
5

当条件表达式为 false 时,终止循环。

实例2:条件表达式为 true,将会产生死循环

#!/bin/bash
while [ 1 -eq 1 ]; do
echo "yes"
done 也可以条件表达式直接用 true:
#!/bin/bash
while true; do
echo "yes"
done

死循环有什么作用那?

可以用来后台运行检测脚本,如下是是一个检测脑裂的脚本

我们只需要在命令行中输入 nohup bash naolie.sh & 即可在后台持续运行该脚本

例子1:持续检测内存剩余量,并每隔1分钟输出至一个文件中

[root@ken ~]# cat test15.sh
#!/bin/bash
while true
do
mem=`free -h | grep “Mem” | cut -d “M” -f 4 | tr -d ” “`
echo “$(date “+%F %T”) $mem” >> /root/free_mem
sleep 2
done

执行结果:

[root@ken ~]# tail -f free_mem

2019-05-31 11:39:11 736

2019-05-31 11:39:13 736

2019-05-31 11:39:15 736

2019-05-31 11:39:17 736

2019-05-31 11:39:19 736

2019-05-31 11:39:21 736

2019-05-31 11:39:23 736

例子2:持续检测内存剩余量,并每隔1分钟输出至一个文件中,并放在后台运行

1.&

[root@ken ~]# bash test15.sh &

这种写法关闭终端之后脚本退出

  1. nohup

    [root@ken ~]# nohup bash test15.sh &

    这种写法终端关闭没有影响

    关掉脚本:

    ps aux

要想使用 while 循环逐行读取 a.txt 文件,有三种方式:

方式 1:

#!/bin/bash
cat ./a.txt | while read LINE; do
echo $LINE
done

方式2:

#!/bin/bash
while read LINE; do
echo $LINE
done < ./a.txt

方式3:

exec < ./a.txt # 读取文件作为标准输出

while read LINE; do

echo $LINE

done

与 while 关联的还有一个 until 语句,它与 while 不同之处在于,是当条件表达式为 false 时才循环,实际使用中比较少,这里不再讲解。

#!/bin/bash
n=0
until [ $n -eq 5 ]
do
let n++
echo "$n"
done

break和continue语句

break 是终止循环。

continue 是跳出当前循环。

示例 1:在死循环中,满足条件终止循环

#!/bin/bash
N=0
while true; do
let N++
if [ $N -eq 5 ]; then
break
fi
echo $N
done # bash test.sh 1
2
3
4

里面用了 if 判断,并用了 break 语句,它是跳出循环。与其关联的还有一个 continue 语句,它是跳出本次循环。

示例 2:举例子说明 continue 用法

#!/bin/bash
N=0
while [ $N -lt 5 ]; do
let N++
if [ $N -eq 3 ]; then
continue
fi
echo $N
done # bash test.sh
1
2
4

当变量 N 等于 3 时,continue 跳过了本次循环,没有执行下面的 echo。

注意:continue 与 break 语句只能循环语句中使用。

[root@ken-node1 ~]# cat test.sh

#!/bin/bash
st=0
while true
do
let st++
if [ $st -eq 5 ];then
continue
elif [ $st -eq 10 ];then
break
else
echo "$st"
fi done
[root@ken-node1 ~]# bash test.sh 1
2
3
4
6
7
8
9

break和continue语句

两个语句只能用在循环语句中!

break 是终止循环。

continue 是跳出当前循环。

例子1:break

[root@ken ~]# cat test19.sh

#!/bin/bash
num=1
while true
do
let num++
if [ $num -eq 5 ];then
break
fi
echo “$num”
done

执行结果:

[root@ken ~]# bash test19.sh

2

3

4

例子2:continue

[root@ken ~]# cat test20.sh

#!/bin/bash
num=0
while true
do
let num++
if [ $num -eq 5 ];then
continue
fi
echo “$num”
done

执行结果:

[root@ken ~]# bash test20.sh | head

1

2

3

4

6

7

8

9

10

11

实际用法:

#!/bin/bash
while true
do
num=`ss -tnl | grep “80” | wc -l`
if [ $num -eq 0 ];then
systemctl restart nginx
if [ $? -ne 0 ];then
echo “`date ‘+%F %T’` 152.136.127.116腾讯云主机web服务宕机,技术流ken请尽快上线修复!” | mail -s “152.136.127.116腾讯云主机 web宕机” 1614833188@qq.com
exit
else
echo “`date ‘+%F %T’` 152.136.127.116腾讯云主机 web宕机已自动恢复” | mail -s “152.136.127.116腾讯云主机 web宕机恢复” 1614833188@qq.com
continue
fi
fi
done

case语句

case 语句一般用于选择性来执行对应部分块命令。

case 模式名 in 模式 1)

  命令

  ;;

模式 2)

  命令

  ;; *)

  不符合以上模式执行的命令

esac

每个模式必须以右括号结束,命令结尾以双分号结束,最后一个模式不需要添加;;。

示例1:根据位置参数匹配不同的模式

#!/bin/bash case $1 in
start)
  echo "start."
;;
stop)
  echo "stop."
;;
restart)
  echo "restart."
;;
*)
  echo "Usage: $0 {start|stop|restart}" esac # bash test.sh
Usage: test.sh {start|stop|restart} # bash test.sh start
start. # bash test.sh stop
stop. # bash test.sh restart
restart。

实例2:

#!/bin/bash
case $1 in
[0-9])
  echo "match number."
  ;;
[a-z])
  echo "match letter."
  ;;
'-h'|'--help')
  echo "help"
  ;;
*)
  echo "Input error!"
  exit
esac # bash test.sh 1
match number. # bash test.sh a
match letter. # bash test.sh -h
help # bash test.sh --help
help

模式支持的正则有:*、?、[ ]、[.-.]、|。后面有章节单独讲解 Shell 正则表达式。

shell编程高级实战

实战1:写一个猜数字的小游戏

要求:

1. 猜对退出

2. 数字随机

3. 使用体验佳

#!/bin/bash
clear
num=`echo $RANDOM`
count=0
while true
do
let count++
read -p "pls enter a num you guess:" guessnum
if [ $guessnum -lt $num ]; then
echo "the num is so smaller!"
elif [ $guessnum -gt $num ];then
echo "the num is so bigger!"
elif [ $guessnum -eq $num ];then
echo "right!wonderful! "
break
else
echo "good bye"
exit
fi
done

echo -e "\033[36myou guess $count times\033[0m" #-e允许对下面列出的加反斜线转义的字符进行解释.

实战2:检测当前教室在线IP地址

要求:

1.显示美观

#!/bin/bash
. /etc/init.d/functions
ip=172.20.10.
for i in {1..255}
do
if ping -c 1 $ip$i &>/dev/null ;then
echo -n "$ip$i" #-n表示不输出行尾的换行符
success
echo ""
else
echo -n "$ip$i"
failure
echo ""
fi
done

实战3:检查软件包是否安装

要求:

1.用户输入软件名即可进行查询

#!/bin/bash
read -p "pls enter a softname:" softname
if rpm -q $softname &>/dev/null ;then
echo "the $softname is already installed"
else
echo "the $softname" is not installed
fi

实战4:打印九九乘法表

#!/bin/bash
for i in `seq 9`
do
for a in `seq 9`
do
if [ $a -le $i ];then
echo -n "$a*$i=$(($i*$a)) "
fi
done
echo ""
done

补充练习题

1.实现简单计算器(加减乘除)

#!/bin/bash
read -p "请输入第一个数字:" a
read -p "请输入运算符[+-*/]:" b
read -p "请输入第二个数字:" c
if [ -n "$a" -a -n "$b" -a -n "$c" ];then
if [ "$b" == "+" ];then
echo "$a+$c=$(($a+$c))"
elif [ "$b" == "-" ];then
echo "$a-$c=$(($a-$c))"
elif [ "$b" == "*" ];then
echo "$a*$c=$(($a*$c))"
elif [ "$b" == "/" ];then
echo "$a/$c=$(($a/$c))"
else
echo "请输入+—*%"
fi
else
echo "请按照要求输入内容!"
fi

2. 批量创建100个以数字开头的文件,并每隔一秒钟输出到终端

#!/bin/bash
for i in {1..100}
do
touch ${i}.txt
echo "${i}.txt"
sleep 1
done

3.动态持续监测本机linux系统内存剩余量(仅显示数值),并在终端输出

#!/bin/bash
while true
do
mem=`free -h | grep "Mem" | cut -d "M" -f 4 | tr -d " "`
echo $mem
sleep 1 done

课后练习题

写一个脚本: 实现自动化一键部署NFS服务器端和客户端

第二个脚本:实现批量化检测当前教室主机在线状况,在线主机保存至一个文件中

第三个脚本:实现批量化创建100个用户,并创建8位随机密码,且可登陆

第四个脚本:找出系统中含有某个关键词的文件,并输出到终端,关键词用户输入指定

第五个脚本:批量判断当前目录下所有文件类型

补充:shell练习题

1. 每一秒钟输出/root下的文件至屏幕

2. 打印出包含某个关键词的文件(关键词执行脚本时接收)

3. 统计系统中以.sh结尾的文件总大小,输出结果以kb为单位

参考答案:

1.

#!/bin/bash
for file in `ls /root`
do
echo $file
sleep 1
done
#!/bin/bash
key=$1
for file in `find / -type f`
do
grep "$key" $file &>/dev/null
if [ $? -eq 0 ];then
echo $file
sleep 1
fi
done
#!/bin/bash
sum=0
for size in `find /root -name "*.sh" -exec ls -l {} \; | cut -d " " -f 5`
do
let sum+=$size
done
echo "$((sum/1024))kb"

Shell编程、part3的更多相关文章

  1. Linux学习笔记(17) Shell编程之基础

    1. 正则表达式 (1) 正则表达式用来在文件中匹配符合条件的字符串,正则是包含匹配.grep.awk.sed等命令可以支持正则表达式:通配符用来匹配符合条件的文件名,通配符是完全匹配.ls.find ...

  2. shell编程:定义简单标准命令集

    shell是用户操作接口的意思,操作系统运行起来后都会给用户提供一个操作界面,这个界面就叫shell,用户可以通过shell来调用操作系统内部的复杂实现,而shell编程就是在shell层次上进行编程 ...

  3. Linux Shell编程入门

    从程序员的角度来看, Shell本身是一种用C语言编写的程序,从用户的角度来看,Shell是用户与Linux操作系统沟通的桥梁.用户既可以输入命令执行,又可以利用 Shell脚本编程,完成更加复杂的操 ...

  4. Shell编程菜鸟基础入门笔记

    Shell编程基础入门     1.shell格式:例 shell脚本开发习惯 1.指定解释器 #!/bin/bash 2.脚本开头加版权等信息如:#DATE:时间,#author(作者)#mail: ...

  5. Linux_10------Linux之shell编程------变量

    .-9 vim num.sh #! /bin/bash num1=$1 num2=$2 sum=$(($num1+$num2)) #变量sum是num1和num2的综合 echo $sum 执行 ./ ...

  6. 需要交互的shell编程——EOF(转载)

    在shell编程中,”EOF“通常与”<<“结合使用,“<<EOF“表示后续的输入作为子命令或子shell的输入,直到遇到”EOF“, 再次返回到主调shell,可将其理解为分 ...

  7. ****CodeIgniter使用cli模式运行,把php作为shell编程

    shell简介 在计算机科学中,Shell俗称壳(用来区别于核).而我们常说的shell简单理解就是一个命令行界面,它使得用户能与操作系统的内核进行交互操作. 常见的shell环境有:MS-DOS.B ...

  8. Shell 编程基础之变量和环境变量

    一.变量赋值和引用 Shell 编程中,使用变量无需事先声明,同时变量的命名不惜遵循如下规则: 首个字符必须为字母(a-z,A-Z)或者_ 变量名中间不能有空格,可以使用_连接 不能使用其他表达符号 ...

  9. Linux Shell编程基础

    在学习Linux BASH Shell编程的过程中,发现由于不经常用,所以很多东西很容易忘记,所以写篇文章来记录一下 ls   显示当前路径下的文件,常用的有 -l 显示长格式  -a 显示所有包括隐 ...

随机推荐

  1. linux ngxtop安装安装及使用

    写在前面: ngxtop是Nginx日志实时分析利器 1.下载 下载地址:https://github.com/lebinh/ngxtop  下载zip文件到本地 登录linux服务器,定位到安装目录 ...

  2. 交互式数据可视化-D3.js(三)比例尺

    线性比例尺 线性比例尺是常用比例尺常用方法有: var linear = d3.scaleLinear() - 创建一个定量的线性比例尺. linear.domain([numbers]) - 定义或 ...

  3. MySQL显示ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (10061)解决方法

    MySQL显示ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (10061)解决方法 2.4K 解决方法: 第一步cd ...

  4. Druid连接池错误(数据库版本问题)

    前提 jdbc驱动: mysql-connector-java.8.0.13.jar durid依赖包:durid-1.0.9.jar mysql版本: mysql 8.0 1 错误 1.1 错误一 ...

  5. 解决 Maven项目进行编译( mvn compile )时出现的错误

    错误信息: 在 pom.xml 文件 设置一下Maven的属性 <!--Maven 属性--> <properties> <!--项目的编码格式--> <pr ...

  6. 第二篇【Zabbix客户端的完整布署】

    关于Zabbix服务端布署请查看 1.上传zabbix安装包(源码包默认(Server和Agent是一起的)) [root@sms-v2 ~]# ll /root/ -rw-r--r-- root r ...

  7. ubuntu编译安装openssl

    http://blog.bccn.net/%E9%9D%99%E5%A4%9C%E6%80%9D/66642 su root  不然权限不够 cd /usr/src wget https://www. ...

  8. CF#356 div2 C 猜数字

    C. Bear and Prime 100 time limit per test 1 second memory limit per test 256 megabytes input standar ...

  9. 【BZOJ2459】 [BeiJing2011]神秘好人

    Description 有一个神秘好人跟Bdcxq玩一个游戏,如果Bdcxq成功完成了这个游戏,那么他将会得到一件礼物. 这个游戏是这样的: 有一个梯子形的图如下,每条边都有一个权值. 神秘好人一开始 ...

  10. pip安装源和虚拟环境的搭建

    一.pip安装源 1.介绍 采用国内源,加速下载模块的速度 常用pip源: 豆瓣:https://pypi.douban.com/simple 阿里:https://mirrors.aliyun.co ...