Shell基础(三):使用for循环结构、使用while循环结构、基于case分支编写脚本、使用Shell函数、中断及退出
一、使用for循环结构
目标:
本案例要求编写一个Shell脚本chkhosts.sh,利用for循环来检测多个主机的存活状态,相关要求及说明如下:
1> 对192.168.4.0/24网段执行ping检测
2> ping检测可参考前一天的pinghost.sh脚本
3> 脚本能遍历ping各主机,并反馈存活状态
执行检测脚本以后,反馈结果如下图所示。
方案:
在Shell脚本应用中,常见的for循环采用遍历式、列表式的执行流程,通过指定变量从值列表中循环赋值,每次复制后执行固定的一组操作。
for循环的语法结构如下所示:
for 变量名 in 值列表
do
命令序列
done
步骤:
步骤一:练习for循环基本用法
脚本1,通过循环读取账户文件user.txt,批量创建账户:
[root@svr5 ~]# vim for01.sh
#!/bin/bash
for i in $(cat root/user.txt)
do
useradd $i
echo "123456" | passwd --stdin $i
done
[root@svr5 ~]# chmod +x for01.sh
步骤二:批量检测多个主机的存活状态
1)编写脚本如下:
[root@svr5 ~]# vim chkhosts.sh
#!/bin/bash
for IP in {1..254}
do
ping -c 3 -i 0.2 -W 3 192.168.4.$IP &> /dev/null
if [ $? -eq 0 ] ; then
echo "Host 192.168.4.$IP is up."
else
echo "Host 192.168.4.$IP is down."
fi
done
[root@svr5 ~]# chmod +x chkhosts.sh
2)测试、验证脚本
[root@svr5 ~]# vim chkhosts.sh
… …
[root@svr5 ~]# ./chkhosts.sh
Host 192.168.4.5 is up.
Host 192.168.4.6 is down
… …
二、使用while循环结构
目标:
本案例要求编写三个使用while循环的脚本程序,分别实现以下目标:
1> 批量添加用户账号:stu1-stu20
2> 批量删除用户账号:stu1-stu20
3> 检测192.168.4.0/24网段,列出不在线的主机地址
方案:
while循环属于条件式的执行流程,会反复判断指定的测试条件,只要条件成立即执行固定的一组操作,直到条件变化为不成立为止。所以while循环的条件一般通过变量来进行控制,在循环体内对变量值做相应改变,以便在适当的时候退出,避免陷入死循环。
while循环的语法结构如下所示:
while 条件测试
do
命令序列
done
步骤:
步骤一:批量添加用户账号stu1-stu20
添加的账号有固定的前缀stu(练习中可自行设置),多个账号从1开始编号,比如stu1、stu2、stu3、……、stu20。—— 编写脚本uaddwhile.sh,实现批量添加这20个用户账号的功能,密码均设为123456。
脚本编写参考如下:
[root@svr5 ~]# vim uaddwhile.sh
#!/bin/bash
PREFIX="stu" //定义用户名前缀
i=1
while [ $i -le 20 ]
do
useradd ${PREFIX}$i //添加的用户名为:前缀+编号
echo "123456" | passwd --stdin ${PREFIX}$i &> /dev/null
let i++
done
[root@svr5 ~]# chmod +x uaddwhile.sh
执行脚本并验证结果:
[root@svr5 ~]# vim uaddwhile.sh
[root@svr5 ~]# ./uaddwhile.sh
[root@svr5 ~]# grep ^stu /etc/passwd //检查添加的用户
stu1:x:531:531::/home/stu1:/bin/bash
stu2:x:532:532::/home/stu2:/bin/bash
stu3:x:533:533::/home/stu3:/bin/bash
stu4:x:534:534::/home/stu4:/bin/bash
stu5:x:535:535::/home/stu5:/bin/bash
… …
步骤二:批量删除用户账号stu1-stu20
针对前面执行uaddwhile.sh脚本批量添加的用户账号,再建立一个批量删除这些账号的脚本udelwhile.sh。结构类似,只要替换为删除相关的操作即可。
脚本编写参考如下:
[root@svr5 ~]# vim udelwhile.sh
#!/bin/bash
PREFIX="stu"
i=1
while [ $i -le 20 ]
do
userdel -r ${PREFIX}$i &> /dev/null
let i++
done
[root@svr5 ~]# chmod +x udelwhile.sh
执行脚本并验证结果:
[root@svr5 ~]# ./udelwhile.sh
[root@svr5 ~]# grep ^stu /etc/passwd //再检查已无相应账号信息
[root@svr5 ~]#
步骤三:检测192.168.4.0/24网段,列出不在线的主机地址
1)任务需求及思路分析
要求的是“检测192.168.4.0/24网段,列出不在线的主机地址”。
检测目标是一个网段,其网络部分“192.168.4.”可以作为固定的前缀;而主机部分包括从1~254连续的地址,所以可结合while循环和自增变量进行控制。
2)根据实现思路编写脚本
[root@svr5 ~]# vim chknet.sh
#!/bin/bash
NET="192.168.4."
i=1
while [ $i -le 254 ]
do
IP="${NET}$i"
ping -c 3 -i 0.2 -W 1 $IP &> /dev/null
if [ $? -eq 0 ] ; then
echo "Host $IP is up."
else
echo "Host $IP is down."
fi
let i++
done
[root@svr5 ~]# chmod +x chknet.sh
3)测试、验证脚本
[root@svr5 ~]# ./chknet.sh
Host 192.168.4.1 is down.
Host 192.168.4.2 is down.
Host 192.168.4.3 is down.
Host 192.168.4.4 is down.
Host 192.168.4.5 is up.
.. ..
Host 192.168.4.250 is down.
Host 192.168.4.251 is down.
Host 192.168.4.252 is down.
Host 192.168.4.253 is down.
Host 192.168.4.254 is down.
三、基于case分支编写脚本
目标:
本案例要求编写test.sh脚本,相关要求如下:
1> 能使用redhat、fedora控制参数
2> 控制参数通过位置变量$1传入
3> 当用户输入redhat参数,脚本返回fedora
4> 当用户输入fedora参数,脚本返回redhat
5> 当用户输入其他参数,则提示错误信息
方案:
case分支属于匹配执行的方式,它针对指定的变量预先设置一个可能的取值,判断该变量的实际取值是否与预设的某一个值相匹配,如果匹配上了,就执行相应的一组操作,如果没有任何值能够匹配,就执行预先设置的默认操作。
case分支的语法结构如下所示:
case 变量值 in
模式1)
命令序列1 ;;
模式2)
命令序列2 ;;
.. ..
*)
默认命令序列
esac
步骤:
步骤一:编写脚本文件
脚本编写参考如下:
[root@svr5 ~]# vim test.sh
#!/bin/bash
case $1 in
redhat)
echo "fedora";;
fedora)
echo "redhat";;
*) //默认输出脚本用法
echo "用法: $0 {redhat|fedora}"
exit 1
esac
[root@svr5 ~]# chmod +x test.sh
步骤二:验证、测试脚本
未提供参数,或提供的参数无法识别时,提示正确用法:
[root@svr5 ~]# ./test.sh
用法: ./test.sh {redhat|fedora}
确认可响应redhat控制参数:
[root@svr5 ~]# ./test.sh redhat
fedora
确认可响应fedora控制参数:
[root@svr5 ~]# ./test.sh fedora
redhat
四、使用Shell函数、中断及退出
目标:
本案例要求编写两个Shell脚本,相关要求如下:
• 一个funexpr.sh脚本:由用户在执行时提供2个整数值参数,计算这2个整数的加、减、乘、除结果
方案:
在Shell脚本中,将一些需重复使用的操作,定义为公共的语句块,即可称为函数。通过使用函数,可以使脚本代码更加简洁,增强易读性,提高Shell脚本的执行效率
1)函数的定义方法
格式1:
function 函数名 {
命令序列
.. ..
}
格式2:
函数名() {
命令序列
.. ..
}
2)函数的调用
直接使用“函数名”的形式调用,如果该函数能够处理位置参数,则可以使用“函数名 参数1 参数2 .. ..”的形式调用。
注意:函数的定义语句必须出现在调用之前,否则无法执行。
3) 测试语法格式
[root@svr5 ~]# mycd(){ //定义函数
> mkdir /test
> cd /test
> }
[root@svr5 ~]# mycd //调用函数
[root@svr5 ~]# mycd(){ //定义函数
> mkdir $1
> cd $1
> }
[root@svr5 ~]# mycd /abc //调用函数
[root@svr5 ~]# mycd /360 //调用函数
步骤:
步骤一:编写funexpr.sh脚本
1)任务需求及思路分析
用户在执行时提供2个整数参数,这个可以通过位置变量$1、$2读入。
针对给定的两个整数,四则运算可以视为一组操作,可以定义为一个函数,依次负责加减乘除运算并输出结果。
调用函数时,将用户提供的两个参数传递给函数处理。
2)根据实现思路编写脚本文件
[root@svr5 ~]# vim funexpr.sh
#!/bin/bash
myexpr() {
echo "$1 + $2 = $[$1+$2]"
echo "$1 - $2 = $[$1-$2]"
echo "$1 * $2 = $[$1*$2]"
echo "$1 / $2 = $[$1/$2]"
}
myexpr $1 $2
[root@svr5 ~]# chmod +x funexpr.sh
3)测试脚本执行效果
[root@svr5 ~]# ./funexpr.sh 43 21
43 + 21 = 64
43 - 21 = 22
43 * 21 = 903
43 / 21 = 2
[root@svr5 ~]# ./funexpr.sh 1234 567
1234 + 567 = 1801
1234 - 567 = 667
1234 * 567 = 699678
1234 / 567 = 2
五、中断及退出
目标:
本案例要求编写两个Shell脚本,相关要求如下:
1> 从键盘循环取整数(0结束)并求和,输出最终结果
2> 跳过1~20以内非6的倍数,输出其他数的平方值,设定退出代码为2
方案:
通过break、continue、exit在Shell脚本中实现中断与退出的功能。
break可以结束整个循环;continue结束本次循环,进入下一次循环;exit结束整个脚本,案例如下:
[root@svr5 ~]# cat /root/test.sh
#!/bin/bash
for i in {1..5}
do
if [ $i -eq 3 ];then
break #这里将break替换为continue,exit分别测试脚本执行效果
fi
echo $i
done
echo 程序结束
步骤:
步骤一:编写脚本sum.sh
1)编写脚本文件
[root@svr5 ~]# vim sum.sh
#!/bin/bash
while read -p "请输入待累加的整数(0表示结束):" x
do
[ $x -eq 0 ] && break
SUM=$[SUM+x]
done
echo "总和是:$SUM"
[root@svr5 ~]# chmod +x chkint.sh
步骤二:编写sum.sh脚本文件
1)编写脚本文件
[root@svr5 ~]# vim mysum.sh
#!/bin/bash
i=0
while [ $i -le 20 ]
do
let i++
[ $[i%6] -ne 0 ] && continue
echo $[i*i]
done
exit 2
[root@svr5 ~]# chmod +x sum.sh
Shell基础(三):使用for循环结构、使用while循环结构、基于case分支编写脚本、使用Shell函数、中断及退出的更多相关文章
- Shell 03 for while case 函数 中断及退出
一.for循环 1.脚本1,通过循环批量显示5个hello world ( in 1 2 3 4 5 ) 2.脚本2,通过循环批量显示10个hello world ( in {1..10} ...
- shell基础(三)
函数 1.可以带function fun() 定义,也可以直接fun() 定义,不带任何参数: 2.参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值: 3.必须 ...
- shell编程中的 三种结构: 条件if/选择结构case/循环for/while/until等结构 和 函数的用法
shell 函数的使用 (md中, 列表本身是有格式的, 他要产生缩进, 其次,列表项和列表项之间, 可以留有一个空行, 是合法的, 允许的) shell函数,就是 就相当于一个命令来看待和处理的, ...
- 045 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 07 for循环应用及局部变量作用范围
045 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 07 for循环应用及局部变量作用范围 本文知识点:for循环应用及局部变量作用范围 for循环 w ...
- 040 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 02 while循环的执行流程
040 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 02 while循环的执行流程 本文知识点:while循环的执行流程 三种循环结构中的第一种--wh ...
- Python基础三(选择,循环)
序 首先我们知道程序的执行有三种结构:顺序.选择.循环三种结构,而为了方便我们书写和多次利用我们就需要把一段代码封装器来,这就是方法.今天我就说的是程序的基本结构的格式和方法. 注:所有的程序都可以通 ...
- Shell基础(二):Shell中的数值运算、条件测试操作、使用if选择结构
一.Shell中的数值运算 目标: 本案例要求熟悉Linux Shell环境的特点,主要练习以下操作: 1> 使用expr.$[ ].let等整数运算工具:定义变量X=1234,然后计算X与78 ...
- 046 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 08 for循环的注意事项
046 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 08 for循环的注意事项 本文知识点:for循环的注意事项 for循环的注意事项 for循环有3个 ...
- 043 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 05 do-while循环介绍及应用
043 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 05 do-while循环介绍及应用 本文知识点:do-while循环介绍及应用 do-while循 ...
随机推荐
- Linux eth0, eth1, ..., eth%d 的生成【转】
转自:https://blog.csdn.net/xiruanliuwei/article/details/78765255 一直很好奇,Linux下的eth0, eth1,eth2等是如何生成的~ ...
- 同时安装CUDA8.0和CUDA9.0
http://geyao1995.com/CUDA8_CUDA9/ tensorflow1.5版本竟然不支持CUDA8.0了 卸载是不可能卸载的 1.原料准备 CUDA9.0下载:https://de ...
- php number_format()函数 语法
php number_format()函数 语法 number_format()函数怎么用? php number_format()函数表示通过千位分组来格式化数字,语法是number_format( ...
- POJ 2443 Set Operation (按位压缩)
Description You are given N sets, the i-th set (represent by S(i)) have C(i) element (Here "set ...
- [CSP-S模拟测试]:夜鹰与玫瑰(数学)
题目描述 红晕爬上了白玫瑰的花瓣,花刺还没有到达夜莺的心脏,玫瑰的心依旧苍白如终年不化的积雪.由生命铸就的玫瑰不允许存在一丝一毫的瑕疵,假设玫瑰的一片花瓣可以抽象成一个点,一朵玫瑰我们用一个$N\ti ...
- 【Java架构:基础技术】一篇文章搞掂:MyBatis
本文篇幅较长,建议合理利用右上角目录进行查看(如果没有目录请刷新). 本文主要总结于刘增辉的<MyBatisc从入门到精通>一书,有兴趣的朋友可以自行研读 建议仔细研读官方文档: http ...
- (3)C++复合类型
存储数据时必须跟踪的三个属性:信息储存在何处,存储的值,存储的类型 一.数组 #include <iostream> using namespace std; int main() { / ...
- RTTI RAII
RTTI(Run Time Type Identification)即通过运行时类型识别,程序能够使用基类的指针或引用来检查着这些指针或引用所指的对象的实际派生类型. RTTI提供了以下两个非常有用的 ...
- [bzoj4589]Hard Nim(FWT快速沃尔什变化+快速幂)
题面:https://www.lydsy.com/JudgeOnline/problem.php?id=4589 题意 求选恰好n个数,满足每个数都是不大于m的质数,且它们的异或和为0的方案数. 解法 ...
- 线性方程组迭代算法——Jacobi迭代算法的python实现
原理: 请看本人博客:线性方程组的迭代求解算法——原理 代码: import numpy as np max=100#迭代次数上限 Delta=0.01 m=2#阶数:矩阵为2阶 n=3#维数:3X3 ...