文章目录
一、循环语句
1.1 for循环语句
读取不同的变量值,用来逐个执行同一组命令
语句结构
for 变量名 in 取值列表
do
命令序列
done
例1:使用for语句批量添加用户
用户名存放在users.txt文件中,每行一个
[root@localhost opt]# vim user.txt
zhangsan
lisi
wangwu
[root@localhost opt]# vim useradd.sh
#!/bin/bash
user=$(cat /opt/user.txt)
for a in $user
do
useradd $a
echo "123456" | passwd --stdin $a
echo "$a添加成功"
done
[root@localhost opt]# . useradd.sh
更改用户 zhangsan 的密码 。
passwd:所有的身份验证令牌已经成功更新。
zhangsan添加成功
更改用户 lisi 的密码 。
passwd:所有的身份验证令牌已经成功更新。
lisi添加成功
更改用户 wangwu 的密码 。
passwd:所有的身份验证令牌已经成功更新。
wangwu添加成功
同样的可以批量删除用户
[root@localhost opt]# vim useradd.sh
#!/bin/bash
user=$(cat /opt/user.txt)
for a in $user
do
userdel -r $a
#echo "123456" | passwd --stdin $a
echo "$a删除成功"
done
[root@localhost opt]# . useradd.sh
zhangsan删除成功
lisi删除成功
wangwu删除成功
例2:根据IP地址检查主机状态
检测IP地址192.168.179.0-192.168.179.10段落
使用ping命令检测各主机的连通性
[root@localhost opt]# vim ping.sh
#!/bin/bash
for ((i=1;i<=10;i++))
do
ping -c 3 -i 0.2 -w 3 "192.168.179.$i" > /dev/null
if [ $? -eq 0 ];then
echo "主机192.168.179.$i在线"
else
echo "主机192.168.179.$i不在线"
fi
done
[root@localhost opt]# . ping.sh
主机192.168.179.1在线
主机192.168.179.2在线
主机192.168.179.3不在线
主机192.168.179.4不在线
主机192.168.179.5不在线
主机192.168.179.6不在线
主机192.168.179.7不在线
主机192.168.179.8不在线
主机192.168.179.9不在线
主机192.168.179.10不在线
1.2 let命令
- let 对整数进行数学运算
- let和双小括号 (( )) 一样,let 命令也只能进行整数运算,不能对小数(浮点数)或者字符串进行运算
语法格式
let 表达式
或
let "表达式"
或
let '表达式'
以上方式都等价于 ((表达式))
- 当表达式中含有 Shell 特殊字符(例如 |)时,需要用双引号" "或者单引号’ '将表达式包围起来
- 和 (( )) 类似,let 命令也支持一次性计算多个表达式,并且以最后一个表达式的值作为整个 let 命令的执行结果
例:计算1-10偶数/奇数的和
[root@localhost opt]# vim hehe.sh
#!/bin/bash
num=0
for ((i=0;i<=10;i+=2))
do
let num+=$i
done
echo "偶数和为:$num"
[root@localhost opt]# . hehe.sh
偶数和为:30
[root@localhost opt]# vim hehe.sh
#!/bin/bash
num=0
for ((i=1;i<=10;i+=2))
do
let num+=$i
done
echo "奇数和为:$num"
[root@localhost opt]# . hehe.sh
奇数和为:25
1.3 while循环语句
重复测试某个条件,只要条件成立则反复执行
语句结构
while 条件测试操作
do
命令序列
done
例1:使用while循环语句输出1-10数字
扫描二维码关注公众号,回复:
11466133 查看本文章
[root@localhost opt]# vim 10.sh
#!/bin/bash
i=1
while [ $i -le 10 ]
do
echo "$i"
let i++
done
[root@localhost opt]# . 10.sh
1
2
3
4
5
6
7
8
9
10
while死循环
while true:死循环有时候也有奇效,可与用户交互
[root@localhost opt]# vim 10.sh
#!/bin/bash
while true
do
read -p "请输入yes退出:" key
if [ $key = yes ];then
break
fi
done
echo "正常退出"
[root@localhost opt]# . 10.sh
请输入yes退出:no
请输入yes退出:cc
请输入yes退出:sgh
请输入yes退出:yes
正常退出
例3:使用while批量添加用户
- 用户名称以stu开头,按数字顺序进行编号
- 一共添加20个用户,即stu1,stu2…stu20
#!/bin/bash
i=0
while [ $i -le 19 ]
do
let i++
useradd stu$i
echo "123456" | passwd --stdin stu$i &> /dev/null
echo "stu$i添加成功"
done
echo "添加完毕"
[root@localhost opt]# ./useradd.sh
stu1添加成功
stu2添加成功
stu3添加成功
stu4添加成功
stu5添加成功
stu6添加成功
stu7添加成功
stu8添加成功
stu9添加成功
stu10添加成功
stu11添加成功
stu12添加成功
stu13添加成功
stu14添加成功
stu15添加成功
stu16添加成功
stu17添加成功
stu18添加成功
stu19添加成功
stu20添加成功
添加完毕
1.4 untli循环语句
重复测试某个条件,只要条件不成立则反复执行
until 条件测试操作
do
命令序列
done
例:通过循环累加的方式计算1–50的和
#!/bin/bash
i=1
S=0
until [ $i -eq 51 ]
do
let S+=$i
let i++
done
echo "$S"
[root@localhost opt]# ./qiuhe.sh
1275
二、shell函数
2.1 shell函数概述
- shell一个非常重要的特性是它可作为一种编程语言来使用。
- 因为shell是一个解释器,所以它不能对为它编写的程序进行编译,而是在每次从磁盘加载这些程序时对它们进行解释。而程序的加载和解释都是非常耗时的。
- 针对此问题,许多shell(如BourneAgainShell)都包含shell函数,shell把这些函数放在内存中,这样每次需要执行它们时就不必再从磁盘读入。
- shell还以一种内部格式来存放这些函数,这样就不必耗费大量的时间来解释它们
- shell函数将命令序列按格式写在一起
- 可以方便重复使用命令序列
2.2 shell函数定义
通过使用函数,可以对程序进行更加好的组织。将一些相对独立的代码变成函数,
可以提高程序的可读性和重用性。避免重复编写大量相同的代码。
方法1:
函数名() {
函数体
return n
}
方法2:(更加规范)
function 函数名() {
函数体
return n
}
- 其中,return返回的是状态码,需要使用$?调取
- echo 返回的是值,使用变量调用
- 传参:指位置变量
- 可以带function fun() 定义,也可以直接fun() 定义,不带任何参数
- 参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255
#!/bin/bash
function sum(){
#命令序列
read -p "请输入第一个整数:" num1
read -p "请输入第二个整数:" num2
sum=$[$num1+$num2]
#echo 返回的是处理结果值
echo $sum
#return返回的是状态码
return 100
}
number=`sum`
echo $?
echo $number
[root@localhost opt]# bash han.sh
请输入第一个整数:4
请输入第二个整数:4
100
8
2.3 调用函数的方法
- 函数名 [参数1($1)] [参数2($2)]
- 在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数…
- 10不能获取第十个参数,获取第十个参数需要{10}。当n>=10时,需要使用${n}来获取参数
例:
[root@localhost ~]# vim han.sh
#!/bin/bash
function fun1() {
echo "I like you"
}
count=1
while [ $count -le 5 ]
do
fun1
((count++))
done
echo "Eed of loop"
fun1
echo "Eed of scritp"
[root@localhost ~]# bash han.sh
I like you
I like you
I like you
I like you
I like you
Eed of loop
I like you
Eed of scritp
2.4 函数的作用范围
- 函数在Shell脚本中仅在当前Shell环境中有效
- Shell脚本中变量默认全局有效
- 将变量限定在函数内部使用local命令
例:
[root@localhost opt]# vim han.sh
#!/bin/bash
function sum(){
#命令序列
read -p "请输入第一个整数:" num1
read -p "请输入第二个整数:" num2
sum=$[$num1+$num2]
#echo 返回的是处理结果值
local score=100
echo "函数内$score"
echo "和:$sum"
}
sum
echo "函数外$score"
[root@localhost opt]# bash han.sh
请输入第一个整数:5
请输入第二个整数:7
函数内100
和:12
函数外
2.5 递归函数
- 调用自己本身的函数
例:递归遍历目录
#!/bin/bash
function list_files(){
for f in `ls $1`
do
#判断是否是目录
if [ -d "$1/$f" ];then
echo "$2$f"
#递归调用
list_files "$1/$f" " $2"
else
echo "$2$f"
fi
done
}
list_files "/var/log" ""
[root@localhost opt]# bash hanshu.sh
anaconda
anaconda.log
ifcfg.log
journal.log
ks-script-Nw8yvE.log
packaging.log
program.log
storage.log
syslog
X.log
audit
audit.log
......
三、shell数组
3.1应用场景包括
- 获取数组长度
使用for循环获取具体信息,使用下标或索引标记数组中数据的位置
可以存放多种数据,如:整型,长整形,浮点型(单精度,双精度),字符串等 - 获取元素长度
- 遍历元素
- 元素切片
- 元素替换
- 元素删除
… - 数组下标从0开始算
- 数组长度从1开始算
长度为4,数组长度表示为1,2,3,4;数组下标表示为0,1,2,3 - shell中数组是可变长的
3.2 数组定义方法
方法一:
基本格式
数组名=(value0 value1 value2...)
[root@localhost opt]# list=(11 22 33 44 55)
[root@localhost opt]# echo ${list[*]}
11 22 33 44 55
[root@localhost opt]#
方法二:
基本格式
数组名=([0]=value [1]=value [2]=value...)
[root@localhost opt]# list=([0]=55 [1]=44 [2]=33 [3]=22 [4]=11)
[root@localhost opt]# echo ${list[*]}
55 44 33 22 11
方法三:
基本格式
列表名=“value0 value1 value2”
数组名=($列表名)
[root@localhost opt]# sum="22 44 66 88 99"
[root@localhost opt]# list=($sum)
[root@localhost opt]# echo ${list[*]}
22 44 66 88 99
方法四:
基本格式
数组名[0]=“value”
数组名[1]=“value”
数组名[2]=“value”
[root@localhost opt]# list[0]="33"
[root@localhost opt]# list[1]="35"
[root@localhost opt]# list[2]="55"
[root@localhost opt]# list[3]="67"
[root@localhost opt]# list[4]="78"
[root@localhost opt]# echo ${list[*]}
33 35 55 67 78
3.3 数组包括的数据类型与数组操作
3.3.1 数组包括的数据类型
- 数值类型
- 字符类型
使用“”或‘’定义
数组只可存放数值或字符
3.3.2 数组操作
- 获取数组长度
基本格式
${#数组名[@/*]}
例如
[root@localhost opt]# echo ${list[*]}
33 35 55 67 78
[root@localhost opt]# echo ${#list[*]}
5
- 读取某下标赋值
基本格式
${数组名[下标]}
例如
[root@localhost opt]# echo ${list[*]}
33 35 55 67 78
[root@localhost opt]# echo ${list[1]}
35
[root@localhost opt]# echo ${list[0]}
33
- 数组遍历
通过查看数组中的所有元素完成相应的操作
[root@localhost opt]# for v in ${num[*]}
> do
> echo $v
> done
11
22
33
44
55
例如:输出一组数组中的最大值
[root@localhost opt]# vim num.sh
#!/bin/bash
ssr=(32 45 77 18 67)
num=0
for ((i=0;i<${#ssr[*]};i++))
do
if [ ${ssr[i]} -ge $num ];then
num=${ssr[i]}
else
continue
fi
done
echo $num
[root@localhost opt]# bash num6.sh
77
- 数组切片
#{数组名[@/*]:起始位置:长度}
[root@localhost opt]# num=(11 22 33 44 55)
[root@localhost opt]# echo ${num[*]}
11 22 33 44 55
[root@localhost opt]# echo ${num[*]:1:3}
22 33 44
- 数组的替换
${数组名[@/*]/查找字符、替换字符}
[root@localhost opt]# num=(22 44 66 88 99)
[root@localhost opt]# echo ${num[*]}
22 44 66 88 99
[root@localhost opt]# echo ${num[*]/44/55} #临时替换
22 55 66 88 99
[root@localhost opt]# echo ${num[*]}
22 44 66 88 99
[root@localhost opt]# num=(${num[*]/44/55}) #永久替换
[root@localhost opt]# echo ${num[*]}
22 55 66 88 99
- 数组删除
[root@localhost opt]# num=(12 23 34 45 56)
[root@localhost opt]# unset num[1]
[root@localhost opt]# echo ${num[*]}
12 34 45 56
[root@localhost opt]# unset num
[root@localhost opt]# echo ${num[*]}
[root@localhost opt]#