day 05 for循环练习
例题1
批量创建用户,用户名oldxu01-100 密码随机(8~12), 然后将创建成功的用户名及密码写入到一个文件中
#1.创建100个用户
for user in aa{1..10}
do
#2.设定随机密码 (for循环一次,就生成一次)
pass=$(mkpasswd -l 8)
#3.创建用户
useradd $user &>/dev/null
echo "$pass" | passwd --stdin $user &>/dev/null
#4.保存每次循环的用户名和密码
echo "$user:$pass" | tee -a pass.txt
done
例题2
使用case实现批量删除用户。
1.提示用户输入需要删除的用户以及删除的个数。
2.如果用户存在则删除,如果不存在则提示no such user
#! /bin/bash
read -p "请输入删除的用户: " qz
read -p "请输入删除的个数: " hz
read -p "是否要删除: [ y | n ]" Action
case $Action in
y)
for user in $(seq $hz)
do
username=$qz$user
id $username &>/dev/null
if [ $? -eq 0 ];then
userdel -r $username
echo "$username is delete....."
else
echo "$username no such user ....."
continue
fi
done
;;
n)
exit
;;
*)
exit
esac
例题3
写一个倒计时脚本
for i in {10..1}
do
echo -n -e "最后倒计时: $i \r"
sleep 1
done
例题4
编写一个上课随机点名脚本
if [ -s name.txt ];then
User=$(sort --random-sort name.txt |awk 'NR==1')
echo "$User"
grep $User name.txt >> name1.txt
sed -i '/'$User'/d' name.txt
else
cat name1.txt>name.txt
rm -rf name1.txt
fi
###方法2
#1.只循环20次
for i in {1..20}
do
#统计一下名单中的行号
line=$(cat name.txt|wc -l)
#设定一个随机的变量值,但这个值不能超过文件名单的行号
sj=$(( ${RANDOM}%$line+1 ))
# 循环20次,打印20次名单
echo -e " $(sed -n "${sj}p" name.txt) "
sleep 0.1
done
sj=$(( $sj + 1 ))
username=$(sed -n "${sj}p" name.txt)
echo -e 这次回答问题的是: "\033[32m $username \033[0m" 同学。
例题5
抓取https://mirrors.aliyun.com/zabbix/zabbix/4.0/rhel/7/x86_64/页面中的所有rpm包至本地
#1.获取网页的源代码
#2.对网页源代码进行过滤筛选,提取文件名称
#3.将下载的url和文件名称拼接,通过wget下载
Url_File=url.txt
Pkg_Name=$(grep "<a href=" $Url_File | awk -F '"' '{print $2}' | egrep -v "debuginfo|repodata|\.\./")
Get_Url=https://mirrors.aliyun.com/zabbix/zabbix/4.0/rhel/7/x86_64/
for package in $Pkg_Name
do
#完整的下载url地址
url_package=$Get_Url$package
#指定下载至某个目录
wget -O /mnt/$package $url_package &>/dev/null
#判断下载是否正常
if [ $? -eq 0 ];then
echo "软件包: $pkg is ok..."
fi
done
例题6
使用for循环备份mysql库,每个库对应一个sql文件,需要排除没用的。
1.拿到需要的库名称 wordpress jpress zabbix zrlog
2.循环拼接备份命令 mysqldump -uroot -poldxu.com -B zabbix >/mysql/data/zabbix.sql
#!/usr/bin/bash
db_path=/backup/mysql
date_time=$(date +%F)
db_name=$(mysql -uroot -e "show databases;" |sed 1d|egrep -v "*_schema|mysql|test")
[ -d $db_path ] || mkdir $db_path -p
for i in $db_name
do
mysqldump -uroot -B ${i} >$db_path/${i}_${date_time}.sql
if [ -f $db_path/${i}_${date_time}.sql ];then
echo "$i backup is done....."
else
echo "$i backup is error...."
fi
done
#保留最近180天的数据
find $db_path -type f -mtime +180 -delete | xargs rm -rf
例题7
使用for嵌套循环实现分库分表备份。
分库: 值得是多个库分开备份.
分表: 一个库中有多个表,将多个分开备份
备份表
mysqldump -u<username> -p<password> dbname tablename1 tablename2... > /path/to/***.sql
mysqldump -uroot -poldxu.com wordpress t1 >/mysql/data/wordpress/2019-11-1/t1.sql
1.取出所有的库名称
2.取出库对应的所有表
3.将命令拼接在一起完成备份
[root@db01 ~]# cat for-mysql-tables.sh
#!/usr/bin/bash
db_path=/backup/mysql
date_time=$(date +%F)
db_name=$(mysql -uroot -e "show databases;" |sed 1d|egrep -v "*_schema|mysql|test")
#准备备份的目录
[ -d $db_path ] || mkdir $db_path -p
#1.获取所有的库名称
for i in $db_name
do
#1.获取对应库的所有表
db_table=$(mysql -uroot -e "use $i; show tables;"|sed 1d)
for j in $db_table
do
[ -d $db_path/$i/$date_time ] || mkdir $db_path/$i/$date_time -p
mysqldump -uroot $i $j >$db_path/$i/$date_time/${j}.sql
done
done
while循环
while本质上就是循环
只不过while支持条件测试语句
整数比对
字符串比对
正则比对
文件比对
while读入文件的方式比较的特殊
while读入文件按行读取 IFS指定分隔符
for读入文件按空格读取 IFS指定分隔符
while read file
do
echo $file
done < /etc/passwd
循环中的控制语句 ----> for while
exit
break
continue
1.exit,退出整个程序。当脚本碰到exit时,直接退出,剩余不管有多少代码都不执行。
2.break,结束当前循环,但会执行循环之后的所有的代码。
3.continue 忽略本次循环剩余的所有代码,直接进行下一次循环,直到循环结束,然后继续循环之后的代码。
while循环练习题
例题1
使用while读入文件方式,批量创建用户
while read line
do
id $line &>/dev/null
if [ $? -eq 0 ];then
continue
else
useradd $line
fi
done < user.txt
###自行准备user.txt文件,文件内容是要创建的用户名
例题2
使用while读入文件方式,批量创建用户以及密码 文件格式: username:password
while read line
do
user=$(echo $line | awk -F ":" '{print $1}')
pass=$(echo $line | awk -F ":" '{print $2}')
id $user &>/dev/null
if [ $? -eq 0 ];then
continue
else
useradd $user
echo "$pass" | passwd --stdin $user
fi
done <user.txt
例题3
猜数字游戏
1)随机输出一个1-100的数字 echo RANDOM%100+1))
2)要求用户输入的必须是数字(数字处加判断)
3)如果比随机数小则提示比随机数小了 大则提示比随机数大了
4)正确则退出 错误则继续死循环
5)最后统计猜了多少次(猜对了多少次,失败多少次)
SJ=$(($RANDOM%100+1))
i=1
while true
do
read -p "请输入你要猜的数: " Action
if [ $Action -eq $SJ ];then
echo "恭喜你 gdx...."
break
elif [ $Action -lt $SJ ];then
echo "太小了 gdx...."
else
echo "太大了 gdx...."
fi
let i++
done
echo "你总共猜了 $i 次, 失败了 $(( $i-1 )) 次"
例题4
在一个2000多行数据文件,然后有10个新的文件,1-5行数据放到第一个文件里,6-10行数据 放到第二个文件里...46-50数据放到第10个文件里。然后51-55数据在放到第一个文件里
while true
do
for i in $(seq 10)
do
head -5 file.txt >> file_$i.txt
sed -i '1,5d' file.txt
if [ ! -s file.txt ];then
exit
fi
done
done
###方法2
#!/bin/bash
a=0
b=0
while [ $b -lt 2000 ]
do
file=num.txt
while [ $a -lt 10 ]
do
a=$[$a+1]
b=$[$b+5]
echo "$a $b"
line=$(awk "NR==$[$b-4],NR==$b" $file)
echo "$line">>${a}.txt
done
a=0
done