for循环

for循环开发 - 图1
for循环语句和while循环类似,但是for主要用于有次数限制的循环,而不是无限循环。

语法

语法
for循环语句跟着的变量,变量会依次获取in后面的变量值列表内容,以空格分割
每次取一个,然后进入循环,执行do;done之间的代码
然后继续循环

  1. for 变量 in 变量取值列表
  2. do
  3. 代码。。
  4. done

for语法2
还有一种C语言风格的for循环

for ((expr1;expr2;expr3))
do
    代码。。
done

for循环开发 - 图2
示例

[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编码,因为加入了硬件、时间、机器运行状态等信息计算得出。