for循环语句
结构
for 变量名 in 取值列表
do
命令序列
done
流程
首先将列表中的第一个取值赋值给变量,并执行do…done循环体中的命令序列;让后将列表中的第二个取值赋给变量,并执行循环体中的命令序列……以此类推,直到列表中的所有取值用完,跳转到done语句,结束循环
示例
根据姓名列表批量添加用户
[root@localhost ~]$ vim users.txt
zhangsan
lisi
wangwu
zhaoliu
[root@localhost ~]$ vim usersfor.sh
[root@localhost ~]$ bash usersfor.sh
[root@localhost ~]$ cat /etc/passwd
……
zhangsan:x:1000:1000::/home/zhangsan:/bin/bash
lisi:x:1001:1001::/home/lisi:/bin/bash
wangwu:x:1002:1002::/home/wangwu:/bin/bash
zhaoliu:x:1003:1003::/home/zhaoliu:/bin/bash
如果要删除usersfor.sh脚本添加的用户只需将for循环体中添加用户的命令序列改为删除用户即可
[root@localhost ~]$ vim udelfor.sh
#!/bin/bash
ULIST=$(cat /root/users.txt)
for UNAME in $ULIST
do
userdel -r $UNAME &>/dev/null
done
[root@localhost ~]$ bash udelfor.sh
[root@localhost ~]$ id zhangsan
id: chenye: no such user
根据IP地址检查主机状态
[root@localhost ~]$ vim ipadds.txt
127.0.0.1
192.168.2.149
192.168.100.0
192.168.10.101
[root@localhost ~]$ vim for2.sh
#!/bin/bash
HLIST=$(cat /root/addr.txt)
for IP in $HLIST
do
ping -c 3 -i 0.3 -W 3 $IP &>/dev/null
if [ $? -eq 0 ]
then
echo "${IP}处于开启状态"
else
echo "${IP}处于关闭状态"
fi
done
[root@localhost ~]$ bash for2.sh
127.0.0.1处于开启状态
192.168.2.149处于关闭状态
192.168.100.0处于关闭状态
192.168.10.101处于开启状态
while循环语句
结构
while 条件测试操作
do
命令序列
done
示例
1.批量添加带有规律编号的用户
[root@localhost ~]$ cat while.sh
#!/bin/bash
PRE="name"
i=1
while [ $i -le 30 ]
do
useradd ${PRE}$i
echo "123456" | passwd --stdin ${PRE}$i &>/dev/null
let i++
done
删除时把while循环体中添加用户的命令序列改为删除用户的操作即可
[root@localhost ~]$ vim whiledel.sh
#!/bin/bash
PRE="name"
i=1
while [ $i -le 30 ]
do
userdel -r ${PRE}$i
let i++
done
[root@localhost ~]$ bash whiledel.sh
[root@localhost ~]$ id name20
id: name20:无此用户 //提示无此用户
2.猜价格游戏
由脚本预先生成一个随机的价格数目(0~999)作为实际价格,判断 用户猜测的价格是否高出或低于实际价格,给出相应提示后再次要求用户猜测;一直到用户 猜中实际价格为止,输出用户共猜测的次数、实际价格
[root@localhost ~]$ vim while2.sh
#!/bin/bash
PRICE=$(expr $RANDOM % 1000)
TIMES=0
echo "商品价格为0-999,猜猜看是多少"
while true
do
read -p "请输入你猜测的价格" price
let TIMES++
if [ $price -eq $PRICE ]
then
echo "恭喜你猜对了,你猜了${TIMES}次"
exit 0
elif [ $price -gt $PRICE ]
then
echo "猜高了"
else
echo "猜低了"
fi
done
脚本执行结果如下
[root@localhost ~]$ bash while2.sh
商品价格为0-999,猜猜看是多少
请输入你猜测的价格500
猜高了
请输入你猜测的价格250
猜高了
请输入你猜测的价格125
猜高了
请输入你猜测的价格62
猜低了
请输入你猜测的价格93
猜低了
请输入你猜测的价格109
猜低了
请输入你猜测的价格117
猜低了
请输入你猜测的价格121
猜高了
请输入你猜测的价格119
猜低了
请输入你猜测的价格120
恭喜你猜对了,你猜了10次
until循环语句
结构
until 条件测试操作
do
命令序列
done
示例
计算1-100的和
[root@localhost ~]$ vim until.sh
#!/bin/bash
i=0;s=0
until [ $i -eq 100 ]
do
let "i=$i+1"
let "s=$s+$i"
done
echo 'sum(1..100)='$s
[root@localhost ~]$ bash until.sh
sum(1..100)=5050
Shell函数
Shell函数定义的方法
[function] 函数名() {
命令序列
[return x]
}
function”关键字表示定义一个函数,可以省略;
“{”符号表示函数执行命令的入口,该符号可以与函数名同行也可以在函数名下一行的句首;
“}”符号表示函数体结束,两个大括号之间{ }是函数体;
“命令序列”部分可以是任意的 Shell 命令,也可以调用其他函数;
“return”表示退出函数返回一个退出值,通过返回值判断执行是否成功,也可以使用 exit 终止整个 Shell 脚本。
示例
[root@localhost ~]$ vim until.sh
#!/bin/bash
zhangsan(){
echo "my name is zhangsan"
echo "nihao"
}
lisi(){
echo "my name is lisi"
echo "ni hao"
}
zhangsan
lisi
zhangsan
运行结果如下
[root@localhost ~]$ bash until.sh
my name is zhangsan
nihao
my name is lisi
ni hao
my name is zhangsan
nihao
函数变量的作用范围
在 Shell 脚本中函数的执行并不会开启一个新的子 Shell,而是仅在当前定义的Shell 环境中有效。如果 Shell脚本中的变量没有经过特殊设定,默认在整个脚本中都是有效的。 在编写脚本时,有时需要将变量的值限定在函数内部,可以通过内置命令 local 来实现。函 数内部变量的使用,可以避免函数内外同时出现同名变量对脚本结果的影响。local 命令的 使用如下所示。
[root@localhost ~]$ vim hhh.sh
aaa(){
local i=1
echo $i
}
i=2
aaa
echo $i
[root@localhost ~]$ bash hhh.sh
1
2
函数从参数
用法
函数名称 参数 1 参数 2 参数 3 ......
递归函数
[root@localhost ~]$ vim iii.sh
#!/bin/bash
function factorial {
if [ $1 -eq 1 ]
then
echo 1
else
local temp=$[ $1 - 1 ]
local result=$(factorial $temp)
echo $[ $result * $1 ]
fi
}
read -p "Enter value: " value
result=$(factorial $value)
echo "The factorial of $value is: $result"
运行结果如下
[root@localhost ~]$ bash iii.sh
Enter value: 5
The factorial of 5 is: 120
Shell数组
定义方法
方法一:
数组名=(value0 value1 value2 ...)
方法二:
数组名=([0]=value [1]=value [2]=value ...)
方法三:
列表名=”value0 value1 value2 ...”
数组名=($列表名)
方法四:
数组名[0]=”value”
数组名[1]=”value”
数组名[2]=”value”
基本使用方法
首先定义一个数组
[root@localhost ~]$ arr=(1 2 3 4 5)
获取数组长度
[root@localhost ~]$ echo ${#arry[*]}
5
[root@localhost ~]$ echo ${#arry[@]}
5
读取下标赋值(注意:下标从0开始
[root@localhost ~]$ echo ${arry[1]}
2
数组遍历
[root@localhost ~]$ vim array_traverse.sh
#!/bin/bash
arr_number=(1 2 3 4 5)
for v in ${arr_number[@]}
do
echo $v
done
[root@localhost ~]$ bash array_traverse.sh
1
2
3
4
5
数组切片
[root@centos-7 ~]$ echo ${arr[@]} //输出整个数组
1 2 3 4 5
[root@centos-7 ~]$ echo ${arr[@]:0:2} //${数组名[@或*]:起始位置:长度}
1 2
[root@centos-7 ~]$ echo ${arr[@]:2:3}
3 4 5
数组替换
[root@centos-7 ~]$ echo ${arr[@]/4/66} //${数组名[@或*]/查找字符/替换字符}
1 2 3 66 5
[root@centos-7 ~]$ echo ${arr[@]} //并不会替换数组原有内容
1 2 3 4 5
[root@centos-7 ~]$ arr=(${arr[@]/4/66}) //要实现改变原有数组,可通过重新赋值实现
[root@centos-7 ~]$ echo ${arr[@]}
1 2 3 66 5
数组删除
[root@centos-7 ~]$ arr=(1 2 3 4 5)
[root@centos-7 ~]$ unset arr //删除数组
[root@centos-7 ~]$ echo ${arr[*]}
[root@centos-7 ~]$ arr=(1 2 3 4 5)
[root@centos-7 ~]$ unset arr[2] //删除第三个元素
[root@centos-7 ~]$ echo ${arr[*]}
1 2 4 5
Shell脚本调试
sh [-nvx] 脚本名
常用参数的具体含义为:
-n:不会执行该脚本,仅查询脚本语法是否有问题,如果没有语法问题就不显示任 何内容,如果有问题会提示报错。
-v:在执行脚本时,先将脚本的内容输出到屏幕上然后执行脚本,如果有错误,也 会给出错误提示。
-x:将执行的脚本内容输出到屏幕上,这个是对调试很有用的参数。
当脚本文件较长时,可以使用 set 命令指定调试一段脚本。
#!/bin/bash
set -x //开启调试模式
read -p "请输入您的分数(0-100):" GRADE
if [ $GRADE -ge 85 ] && [ $GRADE -le 100 ]
then
echo "$GRADE 分!优秀" set +x //关闭调试模式
elif [ $GRADE -ge 70 ] && [ $GRADE -le 84 ]
then
echo "$GRADE 分,合格" else
echo "$GRADE 分?不合格"
fi