[关闭]
@yanglt7 2018-10-31T14:48:10.000000Z 字数 6866 阅读 698

《Shell 编程》10_for 和 select 循环语句

Shell


10.1 for 循环语法结构

1)变量取值型:

  1. for 变量名 in 变量取值列表 #<== 变量名依次获取变量取值列表内容(以空格分隔),每次仅取一个
  2. do
  3. cmd...
  4. done

2)C 语言型:

  1. for((exp1; exp2; exp3))
  2. do
  3. cmd...
  4. done

10.2 for 循环范例

例 10-1 竖向打印 5、4、3、2、1 这 5 个数字。

  1. #!/bin/bash
  2. #for n in 5 4 3 2 1 #<== 直接列出元素
  3. #for n in {5..1} #<== 利用大括号 {} 生成数字序列
  4. for n in `seq 5 -1 1` #<== 采用 seq 生成数字序列
  5. do
  6. echo "$n"
  7. done

例 10-2 获取当前目录下的目录或文件名,并将其作为变量列表打印输出。

  1. #!/bin/bash
  2. for filename in `ls`
  3. do
  4. echo "$filename"
  5. done

例 10-3 用 for 循环批量修改文件扩展名。

  1. [root@web001 scripts]# ll test/
  2. total 0
  3. -rw-r--r-- 1 root root 0 Oct 26 12:47 test.gif
  4. -rw-r--r-- 1 root root 0 Oct 26 12:47 ylt.gif
  5. [root@web001 scripts]# cat 222.sh
  6. #!/bin/bash
  7. cd test
  8. for filename in `ls|grep "gif$"`
  9. do
  10. mv $filename `echo $filename|cut -d . -f1`.txt
  11. done
  12. [root@web001 scripts]# sh 222.sh
  13. [root@web001 scripts]# ll test/
  14. total 0
  15. -rw-r--r-- 1 root root 0 Oct 26 12:47 test.txt
  16. -rw-r--r-- 1 root root 0 Oct 26 12:47 ylt.txt
  1. 2:通过 rename 命令实现
  2. [root@web001 test]# rename "txt" "gif" *.txt
  3. [root@web001 test]# ll
  4. total 0
  5. -rw-r--r-- 1 root root 0 Oct 26 12:47 test.gif
  6. -rw-r--r-- 1 root root 0 Oct 26 12:47 ylt.gif

例 10-4 在 Linux 下批量修改文件名,将 “_finished” 去掉。

  1. [root@web001 test]# ll
  2. total 4
  3. -rw-r--r-- 1 root root 95 Oct 26 14:48 223.sh
  4. -rw-r--r-- 1 root root 0 Oct 26 14:44 test_1_finished.jpg
  5. -rw-r--r-- 1 root root 0 Oct 26 14:44 test_2_finished.jpg
  6. [root@web001 test]# cat 223.sh
  7. #!/bin/bash
  8. for file in `ls *.jpg`
  9. do
  10. mv $file `echo $file|sed 's/_finished//g'`
  11. #mv $file `echo "${file%_finished*}.jpg"`
  12. done
  13. [root@web001 test]# sh 223.sh
  14. [root@web001 test]# ll
  15. total 4
  16. -rw-r--r-- 1 root root 99 Oct 26 14:49 223.sh
  17. -rw-r--r-- 1 root root 0 Oct 26 14:44 test_1.jpg
  18. -rw-r--r-- 1 root root 0 Oct 26 14:44 test_2.jpg

法 2:ls 结合 awk 实现

  1. [root@web001 test]# ll
  2. total 2
  3. -rw-r--r-- 1 root root 0 Oct 26 14:44 test_1.jpg
  4. -rw-r--r-- 1 root root 0 Oct 26 14:44 test_2.jpg
  5. [root@web001 test]# ls|awk -F "." '{print $0,$1,$2}'
  6. test_1.jpg test_1 jpg
  7. test_2.jpg test_2 jpg
  8. [root@web001 test]# ls|awk -F "." '{print $0,$1"_finished."$2}'
  9. test_1.jpg test_1_finished.jpg
  10. test_2.jpg test_2_finished.jpg
  11. [root@web001 test]# ls|awk -F "." '{print "mv",$0,$1"_finished."$2}'
  12. mv test_1.jpg test_1_finished.jpg
  13. mv test_2.jpg test_2_finished.jpg
  14. [root@web001 test]# ls|awk -F "." '{print "mv",$0,$1"_finished."$2}'|bash
  15. [root@web001 test]# ll
  16. total 2
  17. -rw-r--r-- 1 root root 0 Oct 26 14:44 test_1_finished.jpg
  18. -rw-r--r-- 1 root root 0 Oct 26 14:44 test_2_finished.jpg

法 3:通过 rename 实现

  1. [root@web001 test]# rename "_finished" "" *.jpg
  2. [root@web001 test]# ll
  3. -rw-r--r-- 1 root root 0 Oct 26 14:44 test_1.jpg
  4. -rw-r--r-- 1 root root 0 Oct 26 14:44 test_2.jpg

例 10-5 通过脚本实现仅 sshd、rsyslog、crond、network、sysstat 服务在开机时自启动。

  1. root@web001 scripts]# for service in `systemctl list-unit-files|grep enabled|awk '{print $1}'`;do systemctl disable $service;done
  2. root@web001 scripts]# for service in crond network rsyslog sshd sysstat;do systemctl enable $service;done
  1. for service in `systemctl list-unit-files|grep enabled|awk '{print $1}'|grep -vE "crond|network|sshd|rsyslog|sysstat"`;do systemctl $service disable;done
  1. systemctl list-unit-files|grep enabled|grep -vE "crond|sshd|network|rsyslog|sysstat"|awk '{print "systemctl disable", $1}'|bash
  2. systemctl list-unit-files|egrep -v "crond|sshd|network|rsyslog|sysstat"|awk '{print "systemctl disable", $1}'|bash
  3. systemctl list-unit-files|grep enabled|grep -vE "crond|sshd|network|rsyslog|sysstat"|awk '{print $1}'|sed -r 's#(.*)#systemctl disble \1#g'|bash

例 10-6 打印九九乘法表。

  1. #!/bin/bash
  2. COLOR='\E[47;30m'
  3. RES='\E[0m'
  4. for num1 in `seq 9`
  5. do
  6. for num2 in `seq 9`
  7. do
  8. if [ $num1 -ge $num2 ]; then
  9. if ((num1*num2>9)); then
  10. echo -en "${COLOR}${num2}*${num1}=$((num1*num2))$RES "
  11. else
  12. echo -en "${COLOR}${num2}*${num1}=$((num1*num2))$RES "
  13. fi
  14. fi
  15. done
  16. echo " "
  17. done

例 10-7 实现 mysql 分库备份脚本

  1. #!/bin/bash
  2. PATH="/application/mysql/bin:$PATH"
  3. DBPATH=/tmp/backup
  4. MYUSER=root
  5. MYPASS=password
  6. SOCKET="/data/3306/mysql.sock"
  7. MYCMD=mysql -u$MYUSER -p$MYPASS -S $SOCKET
  8. [ -d "$DBPATH" ] || mkdir $DBPATH
  9. for dbname in `$MYCMD -e "show databases;"|sed '1,2d'|egrep -v "mysql|schema"`
  10. do
  11. $MYDUMP $dbname|gzip >&DBANME/${dbname}_$(date + %F).sql.gz
  12. done

例 10-8 实现 mysql 分表备份脚本

  1. #!/bin/bash
  2. PATH="/application/mysql/bin:$PATH"
  3. DBPATH=/tmp/backup
  4. MYUSER=root
  5. MYPASS=password
  6. SOCKET=/data/3306/mysql.sock
  7. MYCMD="msyql -u$MYUSER -p$MYPASS -S $SOCKET"
  8. MYDUMP="mysqldump -u$MYUSER -p$MYPASS -S $SOCKET"
  9. [ -d $DBPATH ] || mkdir $DBPATH
  10. for dbname in `$MYCMD -e "show databases"|sed '1,2d'|egrep -v "mysql|schema"`
  11. do
  12. for table in `$MYCMD -e "show tables from $dbname;"|sed '1d'`
  13. do
  14. $MYDUMP $dbname $table|gzip >$DBPATH/${dbname}_$(date +%F)/${dbname}_${table}.sql.gz
  15. done
  16. done

例 10-9 批量创建 5 个系统账号(ylt01-ylt05),并设置密码(密码为 8 位随机数,要求是字符和数字的混合)

  1. #!/bin/bash
  2. . /etc/init.d/functions
  3. user="ylt"
  4. passfile="/tmp/user.log"
  5. for num in `seq -w 05`
  6. do
  7. pass="`echo "test$RANDOM"|md5sum|cut -c3-10`"
  8. useradd $user$num &>/dev/null &&\
  9. echo "$pass"|passwd -stdin $user$num &>/dev/null &&\
  10. echo -e "user:$user$num\tpasswd:$pass">>$passfile
  11. if [ $? -eq 0 ]; then
  12. action "$user$num is ok" /bin/true
  13. else
  14. action "$user$num is fail" /bin/false
  15. fi
  16. done
  17. cat $passfile && >$passfile

10.3 Linux 系统产生随机数的 6 种方法

1)通过系统环境变量($RANDOM)实现

  1. [root@web001 scripts]# echo $RANDOM
  2. 12846
  1. [root@web001 scripts]# echo ylt$RANDOM|md5sum|cut -c 1-5
  2. 06d50
  3. #ylt 就是上述加密字符串

2)通过 openssl 产生随机数

  1. [root@web001 scripts]# openssl rand -base64 8
  2. s50Slkzo6VE=

3)通过时间(date)获得随机数

  1. [root@web001 scripts]# date +%s%N
  2. 1540551763039074396

4)通过 /dev/urandom 配合 chksum 生成随机数

  1. [root@web001 scripts]# head /dev/urandom|cksum
  2. 4002297225 3674

5)通过 UUID 生成随机数

  1. [root@web001 scripts]# cat /proc/sys/kernel/random/uuid
  2. 7f0f19cb-18dc-431e-b29e-a1c9e3ad9f38

6)使用 expect 附带的 mkpasswd 生成随机数

  1. [root@web001 ~]# yum install -y expect
  2. [root@web001 ~]# mkpasswd -l 9 -d 2 -c 3 -C 3 -s 1
  3. 6SnadM<4J
  4. # -l (length of password, default = 9)
  5. # -d (min # of digits, default = 2)
  6. # -c (min # of lowewcase chars, default = 2)
  7. # -C (min # of uppercase chars, default = 2)
  8. # -s (min # of special chars, default = 1)

10.4 select 循环语句介绍及语法

1)select 循环语句为变量取值型

  1. select 变量名 [ in 菜单取值列表 ]
  2. do
  3. cmd...
  4. done

10.5 select 循环范例

例 10-10 用 select 循环打印菜单项的多种实现方法

1)直接使用列表字符串

  1. [root@web001 scripts]# cat 242.sh
  2. #!/bin/bash
  3. select name in ylt yyy lll ttt
  4. do
  5. echo $name
  6. done
  7. [root@web001 scripts]# sh 242.sh
  8. 1) ylt
  9. 2) yyy
  10. 3) lll
  11. 4) ttt
  12. #? 1
  13. ylt
  14. #? 2
  15. yyy
  16. #? 3
  17. lll
  18. #? 4
  19. ttt
  20. #? ^C

2)采用数组做变量列表

  1. [root@web001 scripts]# cat 242_1.sh
  2. #!/bin/bash
  3. array=(ylt yyy lll ttt)
  4. select name in "${array[@]}"
  5. do
  6. echo $name
  7. done

3)把命令结果作为变量列表(菜单项)

  1. [root@web001 scripts]# mkdir -p /tmp/test/{ylt,yyy,lll,ttt}
  2. [root@web001 scripts]# cat 242_2.sh
  3. #!/bin/bash
  4. select name in `ls /tmp/test`
  5. do
  6. echo $name
  7. done

例 10-11 调整 select 循环菜单项的默认提示符及利用 select 变量打印数字序号。

  1. [root@web001 scripts]# cat 244.sh
  2. #!/bin/bash
  3. PS3="please select a num from menu:" # PS3 是系统环境变量用于控制 select 循环的提示符
  4. select name in ylt yyy lll ttt
  5. do
  6. echo -e "I guess you selected the menu is:\n $REPLY) $name"
  7. done
  8. [root@web001 scripts]# sh 244.sh
  9. 1) ylt
  10. 2) yyy
  11. 3) lll
  12. 4) ttt
  13. please select a num from menu:1
  14. I guess you selected the menu is:
  15. 1) ylt
  16. please select a num from menu:^C
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注