for循环

for循环语句和while循环类似,但是for主要用于有次数限制的循环,而不是无限循环。
语法
语法
for循环语句跟着的变量,变量会依次获取in后面的变量值列表内容,以空格分割
每次取一个,然后进入循环,执行do;done之间的代码
然后继续循环
for 变量 in 变量取值列表do代码。。done
for语法2
还有一种C语言风格的for循环
for ((expr1;expr2;expr3))
do
代码。。
done

示例
[root@chaogelinux shell_program]# cat for_test_1.sh
#!/bin/bash
for ((i=1;i<=3;i++))
do
echo $i
done
# 执行脚本
[root@chaogelinux shell_program]# bash for_test_1.sh
1
2
3
解释:
for循环关键字后面的双括号是固定语法,第一个表达式是变量的初始化;第二个是变量的范围设置;第三个变量是变量的自增,自减。
第一个表达式的初始化值,符合第二个的时候,进入循环,执行代码,否则不满足就退出循环。
脚本可以改造为while形式
[root@chaogelinux shell_program]# cat for_test_while.sh
#!/bin/bash
i=1
while ((i<=3))
do
echo $i
((i++))
done
执行结果
[root@chaogelinux shell_program]# bash for_test_while.sh
1
2
3
实践
竖着、倒序打印10~1
多种方法
# 1
[root@chaogelinux shell_program]# cat for_test_2.sh
for num in 10 9 8 7 6 5 4 3 2 1
do
echo $num
done
# 2
[root@chaogelinux shell_program]# cat for_test_2.sh
for num in {10..1}
do
echo $num
done
# 3
# -1 步长,也就是倒序,到1结束
[root@chaogelinux shell_program]# cat for_test_2.sh
for num in `seq 10 -1 1`
do
echo $num
done
for循环遍历目录,及其子目录内容
[root@chaogelinux shell_program]# mkdir -p /tmp/shell_test/{yu,chao,hehe}
[root@chaogelinux shell_program]# ls /tmp/shell_test/
chao hehe yu
[root@chaogelinux shell_program]# touch /tmp/shell_test/{1.txt,2.txt}
[root@chaogelinux shell_program]# ls /tmp/shell_test/
1.txt 2.txt chao hehe yu
# 代码
[root@chaogelinux shell_program]# cat for_test_3.sh
for file in `ls /tmp/shell_test/`
do
echo $file
done
[root@chaogelinux shell_program]# bash for_test_3.sh
1.txt
2.txt
chao
hehe
yu
# 完整脚本
[root@chaogelinux shell_program]# cat for_3.sh
#!/bin/bash
function list_file(){
for file in `ls $1`
do
dir_or_file=$1"/"$file
# 判断如果该文件是目录类型,就继续寻遍该目录
if [ -d $dir_or_file ]
then
list_file $dir_or_file
else
ls $dir_or_file
fi
done
}
list_file $1
批量修改.txt为.log后缀
[root@chaogelinux shell_program]# cat for_test_3.sh
cd /tmp/shell_test/
for file in `ls . |grep "txt$"`
do
rename "txt" "log" $file
done
[root@chaogelinux shell_program]# ls /tmp/shell_test/
1.txt 2.txt chao hehe yu
[root@chaogelinux shell_program]# bash for_test_3.sh
[root@chaogelinux shell_program]# ls /tmp/shell_test/
1.log 2.log chao hehe yu
批量修改文件名,数据源
[root@chaogelinux shell_test]# touch chaoge{1..10}_666.txt
[root@chaogelinux shell_test]# ls -l
总用量 12
-rw-r--r-- 1 root root 0 3月 24 21:06 1.log
-rw-r--r-- 1 root root 0 3月 24 21:06 2.log
drwxr-xr-x 2 root root 4096 3月 24 21:06 chao
-rw-r--r-- 1 root root 0 3月 24 21:21 chaoge10_666.txt
-rw-r--r-- 1 root root 0 3月 24 21:21 chaoge1_666.txt
-rw-r--r-- 1 root root 0 3月 24 21:21 chaoge2_666.txt
-rw-r--r-- 1 root root 0 3月 24 21:21 chaoge3_666.txt
-rw-r--r-- 1 root root 0 3月 24 21:21 chaoge4_666.txt
-rw-r--r-- 1 root root 0 3月 24 21:21 chaoge5_666.txt
-rw-r--r-- 1 root root 0 3月 24 21:21 chaoge6_666.txt
-rw-r--r-- 1 root root 0 3月 24 21:21 chaoge7_666.txt
-rw-r--r-- 1 root root 0 3月 24 21:21 chaoge8_666.txt
-rw-r--r-- 1 root root 0 3月 24 21:21 chaoge9_666.txt
drwxr-xr-x 2 root root 4096 3月 24 21:06 hehe
drwxr-xr-x 2 root root 4096 3月 24 21:06 yu
批量修改所有txt文件,666改为777
[root@chaogelinux shell_program]# cat for_test_4.sh
cd /tmp/shell_test/
for file in `ls *.txt`
do
mv $file `echo $file|sed 's/666/777/g'`
done
批量替换所有的*.txt文件,替换例如为chaoge1.txt
不用for循环,如何操作?
# 直接操作当前目录下所有文件
# 所以不用限制方案,高效即可
[root@chaogelinux shell_test]# rename "_777" "" *.txt
打印乘法表
语法备注
$[] $(())
它们是一样的,都是进行数学运算的。支持+ - * / %:分别为 “加、减、乘、除、取模”。但是注意,bash只能作整数运算,对于浮点数是当作字符串处理的。
代码
for ((a=1;a<=9;a++))
do
for ((b=1;b<=9;b++))
do
# 如果a大于等于b
if [[ a -ge b ]]
then
echo -n "$b * $a = $[a*b] "
fi
done
echo " "
done
每隔两秒访问一次www.pythonav.cn,访问5次
[root@chaogelinux shell_program]# cat for_test_6.sh
#!/bin/bash
for ((i=0;i<5;i++))
do
# -s 不输出 -w格式化输出 -o 写入文件
curl -s -w %{http_code} www.pythonav.cn -o /dev/null
echo
sleep 2
done
高级实践
开发mysql分库备份脚本
开发mysql分库备份脚本
UPDATE mysql.user
SET authentication_string = PASSWORD('chaoge999')
WHERE user = 'root' AND
host = 'localhost';
FLUSH PRIVILEGES;
脚本
$(命令)
`命令`
获取命令执行结果
[root@chaogelinux shell_program]# cat mysql_for.sh
#!/bin/bash
MYUSER=root
MYPWD=chaoge999
DBPATH=/mysql_db_back/
MYCMD="mysql -u$MYUSER -p$MYPWD"
MYDUMP="mysqldump -u$MYUSER -p$MYPWD"
[ ! -d "$DBPATH" ] && mkdir $DBPATH
for dbname in `$MYCMD -e "show databases;"|sed '1d'|egrep -v "mysql|schema"`
do
# 创建数据库同名文件夹
mkdir ${DBPATH}/${dbname}_$(date +%F) -p
# 循环找出所有数据表
for table in `$MYCMD -e "show tables from $dbname;"|sed '1d'`
do
$MYDUMP $dbname $table|gzip > $DBPATH/${dbname}_$(date +%F)/${dbname}_${table}.sql.gz
done
done
批量创建账号,设置密码
#/bin/bash
# author:超哥
# Use LSB init script functions for printing messages, if possible
#
lsb_functions="/lib/lsb/init-functions"
if test -f $lsb_functions ; then
. $lsb_functions
else
# Include non-LSB RedHat init functions to make systemctl redirect work
init_functions="/etc/init.d/functions"
if test -f $init_functions; then
. $init_functions
fi
log_success_msg()
{
echo " SUCCESS! $@"
}
log_failure_msg()
{
echo " ERROR! $@"
}
fi
# 上面是结果美化
user="pyyu"
pwdfile="/tmp/pwd.file"
# seq -w 数字补0
for num in `seq -w 10`
do
# cut -c3-11 输出字符串的3~11位的数字
pwd="`echo '$RANDOM'|md5sum|cut -c3-11`"
useradd $user$num &>/dev/null && \
echo -e "$user${num}:$pwd" >> $pwdfile
if [ $? -eq 0 ]
then
log_success_msg "$user$num is success create."
else
log_failure_msg "$user$num isn't create, fail."
fi
done
echo "----------------分割线"
chpasswd < $pwdfile
cat $pwdfile && >$pwdfile
# 备注,一键删除该测试数据
# for u in `awk -F ':' '{print $1}' /etc/passwd|grep pyyu`;do userdel -rf $u;done
执行结果
[root@chaogelinux shell_program]# bash for_pwd.sh
pyyu01 is success create. [ 确定 ]
pyyu02 is success create. [ 确定 ]
pyyu03 is success create. [ 确定 ]
pyyu04 is success create. [ 确定 ]
pyyu05 is success create. [ 确定 ]
pyyu06 is success create. [ 确定 ]
pyyu07 is success create. [ 确定 ]
pyyu08 is success create. [ 确定 ]
pyyu09 is success create. [ 确定 ]
pyyu10 is success create. [ 确定 ]
----------------分割线
pyyu01:400a275f1
pyyu02:400a275f1
pyyu03:400a275f1
pyyu04:400a275f1
pyyu05:400a275f1
pyyu06:400a275f1
pyyu07:400a275f1
pyyu08:400a275f1
pyyu09:400a275f1
pyyu10:400a275f1
pyyu01:400a275f1
pyyu02:400a275f1
pyyu03:400a275f1
pyyu04:400a275f1
pyyu05:400a275f1
pyyu06:400a275f1
pyyu07:400a275f1
pyyu08:400a275f1
pyyu09:400a275f1
pyyu10:400a275f1
shell生成随机数
在很多场景下,会用到随机数,掌握随机数生成是很有必要
Unix和Linux支持多种校验和程序,但强健性最好且使用最为广泛的校验和算法是MD5和SHA-1。md5sum和sha1sum程序可以对数据应用对应的算法来生成校验和。
使用下列命令计算md5sum:
[root@chaogelinux shell_program]# md5sum 吴亦凡.jpg
d41d8cd98f00b204e9800998ecf8427e 吴亦凡.jpg
如上所示,md5sum是一个长度为32个字符的十六进制串。
我们可以将输出的校验和重定向到一个文件中,以备后用:
[root@chaogelinux shell_program]# expr length 107e4777794da97b144844dc1cf3bb66
32
[root@chaogelinux shell_program]# md5sum 吴亦凡.jpg > 吴亦凡.md5
[root@chaogelinux shell_program]# cat 吴亦凡.md5
d41d8cd98f00b204e9800998ecf8427e 吴亦凡.jpg
# 校验文件 -c, --check 从文件中读取MD5 的校验值并予以检查
[root@chaogelinux shell_program]# md5sum -c 吴亦凡.md5
吴亦凡.jpg: 确定
1.通过RANDOM变量实现
RANDOM变量随机数范围在0~32767,可以添加一些字符串增加密码复杂度。
[root@chaogelinux shell_program]# for ((i=1;i<=10;i++));do echo $RANDOM;done
7614
25608
27755
29856
20608
17067
9519
21753
23631
28249
结合md5sum与RANDOM随机数,并且截取部分字符串
[root@chaogelinux shell_program]# echo "chao$RANDOM"
chao27691
[root@chaogelinux shell_program]# echo "chao$RANDOM"|md5sum
cf0907be522efe40b2bac9cdcca8071e -
[root@chaogelinux shell_program]# echo "chao$RANDOM"|md5sum
9cb4d17c30ef1794159b5fc8ffbaad4c -
# 截取8~15位字符串
[root@chaogelinux shell_program]# echo "chao$RANDOM"|md5sum|cut -c 8-15
3dc1c0c3
[root@chaogelinux shell_program]# echo "chao$RANDOM"|md5sum|cut -c 8-15
d52ff363
通过UUID生成
超哥只在这里讲解最常用的方式,生成随机数
[root@chaogelinux shell_program]# cat /proc/sys/kernel/random/uuid
455baec7-8b9b-48f9-941e-850d326d6b3e
[root@chaogelinux shell_program]# cat /proc/sys/kernel/random/uuid
edd7711a-e79b-402c-8014-0beb00df3329
UUID意思是全球通用唯一识别码,其作用是让分布式系统中所有元素都有唯一的辨识信息,它能够使得网络中的任意一台机器都有唯一的UUID编码,因为加入了硬件、时间、机器运行状态等信息计算得出。
