Shell入门-for循环和select循环

for循环和select循环

本篇主要介绍内容:

  • for循环的定义及使用
  • select循环的用途

for循环

第一种

for循环语句为变量取值型,语法结构如下:

for 变量名 in 变量取值列表
do
	指令...
done

提示:在此结构中“in变量取值列表”可以省略,省略时相当于in“$@”,也就是使用for i就相当于使用for i in“$@”。

在这种for循环语句语法中,for后面的变量名取自变量列表中的元素,每次取一个,并且变量取值列表以空格区分。

第二种

for循环语句称为for循环语句,语法结构如下:

for((exp1;exp2;exp3))
do
	指令..
done

for关键字后的双括号内是三个表达式,第一个是变量初始化(例如:i=0),第二个为变量的范围(例如:i<100),第三个为变量自增或自减(例如:i++)。当第一个表达式的初始化值符合第二个变量的范围时,就进入循环执行;当条件不满足时就退出循环。

总结:

1)如果希望程序持续运行,则多用while,包括守护进程。

2)如果是有限次循环,则多用for,实际工作中使用for的机会更多。

实践-竖向打印数字

竖向打印5、4、3、2、1五个数字

[root@localhost shell]# cat 11_2_1.sh 
#!/bin/bash
#***********************************************
#Author:        luotianhao
#Mail:          tianhao.luo@hand-china.com
#Version:       1.0
#Date:          2021-03-15
#FileName:      11_2_1.sh
#Description:   This is a test script.
#***********************************************
for num in 5 4 3 2 1
do
    echo $num
done
[root@localhost shell]# sh 11_2_1.sh 
5
4
3
2
1

第二种,使用了{}生成数字序列的方法

[root@localhost shell]# cat 11_2_2.sh 
#!/bin/bash
#***********************************************
#Author:        luotianhao
#Mail:          tianhao.luo@hand-china.com
#Version:       1.0
#Date:          2021-03-15
#FileName:      11_2_2.sh
#Description:   This is a test script.
#***********************************************
for n in {5..1}
do
    echo $n
done
[root@localhost shell]# sh 11_2_2.sh 
5
4
3
2
1

第三种,采用seq生成数字序列的用法

[root@localhost shell]# cat 11_2_3.sh 
#!/bin/bash
#***********************************************
#Author:        luotianhao
#Mail:          tianhao.luo@hand-china.com
#Version:       1.0
#Date:          2021-03-15
#FileName:      11_2_3.sh
#Description:   This is a test script.
#***********************************************
for n in $(seq 5 -1 1)
do
    echo $n
done
[root@localhost shell]# sh 11_2_3.sh 
5
4
3
2
1

实践-批量修改文件后缀

将下面的txt文件改为log文件

[root@localhost shell]# ls -l stu*
-rw-r--r-- 1 root root 2 3月   7 15:59 stu_102999_1.txt
-rw-r--r-- 1 root root 2 3月   7 15:59 stu_102999_2.txt
-rw-r--r-- 1 root root 2 3月   7 15:59 stu_102999_3.txt
-rw-r--r-- 1 root root 2 3月   7 15:59 stu_102999_4.txt

提示:通过此题的解答可以学习到sed、awk、rename、mv等命令的实战应用。

我们先将上面的文件名都加上“_finished”,使用awk命令,其中,表示空格,$0表示当前文件名,$1表示按.切割后的前半段,$2表示按.切割后的后半段

[root@localhost shell]# ls stu*|awk -F "." '{print "mv", $0,$1"_finished."$2}'
mv stu_102999_1.txt stu_102999_1_finished.txt
mv stu_102999_2.txt stu_102999_2_finished.txt
mv stu_102999_3.txt stu_102999_3_finished.txt
mv stu_102999_4.txt stu_102999_4_finished.txt
[root@localhost shell]# ls |awk -F "." '{print "mv",$0,$1"_finished.","$2"}' |bash

第一种:采用shell脚本、for循环加sed的方法

[root@localhost shell]# cat 11_5_1.sh 
#!/bin/bash
#***********************************************
#Author:        luotianhao
#Mail:          tianhao.luo@hand-china.com
#Version:       1.0
#Date:          2021-03-15
#FileName:      11_5_1.sh
#Description:   This is a test script.
#***********************************************

for file in `ls stu*.txt`
do
    mv $file `echo $file|sed 's/_finished//g'`
done
[root@localhost shell]# sh 11_5_1.sh
[root@localhost shell]# ls stu*
stu_102999_1.txt  stu_102999_2.txt  stu_102999_3.txt  stu_102999_4.txt

第二种:通过专业的改名命令rename来实现,rename第一个参数为待替换字符串,第二个参数为替换后的值,第三个表示替换哪些文件

[root@localhost shell]# ls stu*
stu_102999_1_finished.jpg  stu_102999_2_finished.jpg  stu_102999_3_finished.jpg  stu_102999_4_finished.jpg
[root@localhost shell]# rename "_finished" "" *.jpg
[root@localhost shell]# ls stu*
stu_102999_1.jpg  stu_102999_2.jpg  stu_102999_3.jpg  stu_102999_4.jpg

实践-打印九九乘法表

[root@localhost shell]# cat 11_8_1.sh 
#!/bin/bash
#***********************************************
#Author:        luotianhao
#Mail:          tianhao.luo@hand-china.com
#Version:       1.0
#Date:          2021-03-15
#FileName:      11_8_1.sh
#Description:   This is a test script.
#***********************************************
COLOR='\E[47;30m'
RES='\E[0m'

for num1 in `seq 9`
do
    for num2 in `seq 9`
    do
        [ $num1 -ge $num2 ] && {
                if (((num1*num2)>9))
                then
                    echo -en "${DOLOR}${num1}x${num2}=$((num1*num2))$RES "
                else
                    echo -en "${COLOR}${num1}x${num2}=$((num1*num2))$RES  "
                fi
        } 
    done
    echo " "
done
[root@localhost shell]# sh 11_8_1.sh 
1x1=1   
2x1=2  2x2=4   
3x1=3  3x2=6  3x3=9   
4x1=4  4x2=8  4x3=12 4x4=16  
5x1=5  5x2=10 5x3=15 5x4=20 5x5=25  
6x1=6  6x2=12 6x3=18 6x4=24 6x5=30 6x6=36  
7x1=7  7x2=14 7x3=21 7x4=28 7x5=35 7x6=42 7x7=49  
8x1=8  8x2=16 8x3=24 8x4=32 8x5=40 8x6=48 8x7=56 8x8=64  
9x1=9  9x2=18 9x3=27 9x4=36 9x5=45 9x6=54 9x7=63 9x8=72 9x9=81  

实践-批量创建10个系统账号

批量创建10个系统账号(oldboy01-oldboy10),并设置密码(密码为随机数,要求是字符和数字的混合)

给数字加前缀0的方法有两种,一种用seq,另一种用{01..10}

[root@localhost bin]# seq -w 10
01
02
03
04
05
06
07
08
09
10
[root@localhost bin]# echo {01..10}
01 02 03 04 05 06 07 08 09 10

无交互设置密码,如下:

[root@localhost bin]# useradd oldgirl
[root@localhost bin]# echo 123456|passwd --stdin oldgirl
更改用户 oldgirl 的密码 。
passwd:所有的身份验证令牌已经成功更新。
[root@localhost bin]# 

设置随机数密码:

[root@localhost bin]# echo $RANDOM
30441
[root@localhost bin]# echo $RANDOM|md5sum
96185997a39274f5f559aca8bc950181  -
[root@localhost bin]# echo $RANDOM|md5sum|cut -c 5-12
a264f7b8
[root@localhost bin]# 

方法一:

[oldboy1@localhost shell]$ cat 11_14_2.sh 
#!/bin/bash
#***********************************************
#Author:        luotianhao
#Mail:          tianhao.luo@hand-china.com
#Version:       1.0
#Date:          2021-03-15
#FileName:      11_14_2.sh
#Description:   This is a test script.
#***********************************************
. /etc/init.d/functions

user="oldboy"
passfile="/u01/learn/shell/user.log"

for num in $(seq -w 1 5)
do
    pass="$(echo "test$RANDOM"|md5sum|cut -c 3-11)"
    useradd $user$num &>/dev/null &&\
        echo "$pass"|passwd --stdin $user$num &>/dev/null &&\
        echo -e "user:$user$num\tpasswd:$pass" >> $passfile
        if [ $? -eq 0 ]
        then
            action "$user$num is ok" /bin/true
        else
            action "$user$num is fail" /bin/false
        fi
    done
echo --------------------------------------
cat $passfile && >$passfile
[root@localhost shell]# vim 11_14_2.sh 
[root@localhost shell]# sh 11_14_2.sh 
oldboy1 is ok                                              [  确定  ]
oldboy2 is ok                                              [  确定  ]
oldboy3 is ok                                              [  确定  ]
oldboy4 is ok                                              [  确定  ]
oldboy5 is ok                                              [  确定  ]
--------------------------------------
user:oldboy1    passwd:62f2a9de0
user:oldboy2    passwd:c2df01198
user:oldboy3    passwd:324d74def
user:oldboy4    passwd:7104be690
user:oldboy5    passwd:fca412731

方法二:

要批量创建密码,可使用chpasswd来实现,chpasswd是一个批量更新用户口令的工具。

给多个用户设置密码的命令为:

chpasswd < 密码文件

但密码文件的内容必须以下面的格式来书写,并且不能有空行;并且用户必须存在

用户名1:口令1
用户名2:口令2

例如:

[root@localhost shell]# cat 11_14_3.sh 
#!/bin/bash
#***********************************************
#Author:        luotianhao
#Mail:          tianhao.luo@hand-china.com
#Version:       1.0
#Date:          2021-03-15
#FileName:      11_14_2.sh
#Description:   This is a test script.
#***********************************************
. /etc/init.d/functions

user="oldboy"
passfile="/u01/learn/shell/user.log"

for num in $(seq -w 8 9)
do
    pass="$(echo "test$RANDOM"|md5sum|cut -c 3-11)"
    useradd $user$num &>/dev/null &&\
        echo -e "$user$num:$pass" >> $passfile
        if [ $? -eq 0 ]
        then
            action "$user$num is ok" /bin/true
        else
            action "$user$num is fail" /bin/false
        fi
    done
echo --------------------------------------
#<====读取密码文件进行密码设置
chpasswd < $passfile
cat $passfile && >$passfile
[root@localhost shell]# sh 11_14_3.sh 
oldboy8 is ok                                              [  确定  ]
oldboy9 is ok                                              [  确定  ]
--------------------------------------
oldboy8:2467d4d93
oldboy9:82bfd134d

产生随机数的6种方法

1.通过系统环境变量($RANDOM)实现,示例代码如下:

[root@localhost shell]# echo $RANDOM
14070
[root@localhost shell]# echo $RANDOM
1366
[root@localhost shell]# 

RANDOM的随机数范围为0~32767,因此,加密性不是很好,可以通过在输出的随机数后增加加密字符串(就是和密码生成有关的一个字符串)的方式解决,最后再一起执行md5sum操作并截取结果的后n位,这样一来,就无法根据随机数范围0~32767来猜出具体结果了。

例如:

[root@localhost shell]# echo "lth$RANDOM"|md5sum|cut -c 8-15
b9bc1312
[root@localhost shell]# echo "lth$RANDOM"|md5sum|cut -c 8-15
25f9a0c1
[root@localhost shell]# 

2.通过openssl产生随机数,例如

[root@localhost shell]# openssl rand -base64 8
k2E/W/FZjGk=
[root@localhost shell]# openssl rand -base64 80
jbZCtvMtQD93zOJdqeex3bTAJ+4QqokUgZOao1J02+yaLevB8IzfXV6dXvRHFvsf
QxbJeQQs0YJNJDuCXLqjInfPQbcnsct+NqnlhZT7Xss=
[root@localhost shell]# 

令数字与大小写字符相结合,并且带上特殊字符,可以达到很长的位数,这样的随机数很安全。

3.通过时间date获得随机数,例如

[root@localhost shell]# date +%s%N
1615800941013912847
[root@localhost shell]# date +%s%N
1615800942636001306
[root@localhost shell]# 

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

[root@localhost shell]# head /dev/urandom|cksum
2932423259 3502
[root@localhost shell]# head /dev/urandom|cksum
2937343284 3780

/dev/random设备存储着系统当前运行环境的实时数据。它可以看作系统在某个时候的唯一值,因此可以用作随机数元数据。我们可以通过文件读取的方式,读到里面的数据。/dev/urandom这个设备的数据与random里的一样。只是,它是非阻塞的随机数发生器,读取操作不会产生阻塞。

5.通过UUID生成随机数

[root@localhost shell]# cat /proc/sys/kernel/random/uuid 
6bc84a00-e601-428f-9910-532b7c6b59e1
[root@localhost shell]# cat /proc/sys/kernel/random/uuid 
f3542880-0ee8-42d0-a08d-b07da8549477
[root@localhost shell]# 

select循环语句介绍及用法

select循环语句的主要作用可能就是创建菜单,在执行带select循环语句的脚本时,输出会按照数字顺序的列表显示一个菜单项,并显示提示符(默认是#? ),同时等待用户输入数字进行选择,下面就来带大家看看生成菜单项的语法及具体案例实践。

第一种

select 变量名 [ in 菜单取值列表 ]
do
	指令...
done

实例一:直接使用列表字符串。

[root@localhost shell]# cat 11_15_1.sh 
#!/bin/bash
#***********************************************
#Author:        luotianhao
#Mail:          tianhao.luo@hand-china.com
#Version:       1.0
#Date:          2021-03-15
#FileName:      11_15_1.sh
#Description:   This is a test script.
#***********************************************
select name in oldboy oldgirl tingting
do
    echo $name
done
[root@localhost shell]# sh 11_15_1.sh 
1) oldboy
2) oldgirl
3) tingting
#? 1
oldboy
#? 2
oldgirl
#? 3
tingting
#? f

#? ^C

实例二:采用数组做变量列表。

[root@localhost shell]# cat 11_15_2.sh 
#!/bin/bash
#***********************************************
#Author:        luotianhao
#Mail:          tianhao.luo@hand-china.com
#Version:       1.0
#Date:          2021-03-15
#FileName:      11_15_2.sh
#Description:   This is a test script.
#***********************************************
array=(oldboy oldgirl tingting)
select name in "${array[@]}"
do
    echo $name
done
[root@localhost shell]# sh 11_15_2.sh 
1) oldboy
2) oldgirl
3) tingting
#? 1
oldboy
#? a

#? 2
oldgirl
#? ^C
[root@localhost shell]# 

实例三:把命令结果作为变量列表(菜单项)

[root@localhost shell]# ls stu*
stu_102999_1.jpg  stu_102999_2.jpg  stu_102999_3.jpg  stu_102999_4.jpg
[root@localhost shell]# vim 11_15_3.sh
[root@localhost shell]# sh 11_15_3.sh 
1) stu_102999_1.jpg  3) stu_102999_3.jpg
2) stu_102999_2.jpg  4) stu_102999_4.jpg
#? 1
stu_102999_1.jpg
#? ^C
[root@localhost shell]# 
[root@localhost shell]# cat 11_15_3.sh 
#!/bin/bash
#***********************************************
#Author:        luotianhao
#Mail:          tianhao.luo@hand-china.com
#Version:       1.0
#Date:          2021-03-15
#FileName:      11_15_3.sh
#Description:   This is a test script.
#***********************************************
select name in $(ls stu*)
do
    echo $name
done

实例四:调整select循环菜单项的默认提示符及利用select变量打印数字序号。本范例重点讲解了select循环的两个特殊变量,其中PS3系统环境变量用于控制select循环的提示符,REPLY变量用于获取菜单项对应的数字,也就是用户输入的数字。

[root@localhost shell]# cat 11_15_4.sh 
#!/bin/bash
#***********************************************
#Author:        luotianhao
#Mail:          tianhao.luo@hand-china.com
#Version:       1.0
#Date:          2021-03-15
#FileName:      11_15_4.sh
#Description:   This is a test script.
#***********************************************
PS3="please select a num from menu:"

select name in oldboy oldgirl tingting
do
    echo -e "i guess you selected the menu is:\n $REPLY) $name"
done
[root@localhost shell]# sh 11_15_4.sh 
1) oldboy
2) oldgirl
3) tingting
please select a num from menu:1
i guess you selected the menu is:
 1) oldboy
please select a num from menu:2
i guess you selected the menu is:
 2) oldgirl
please select a num from menu:4
i guess you selected the menu is:
 4) 
please select a num from menu:3
i guess you selected the menu is:
 3) tingting
please select a num from menu:^C

实例五:打印选择菜单,按照选择一键安装不同的Web服务。

[root@localhost shell]# cat 11_15_10.sh 
#!/bin/bash
#***********************************************
#Author:        luotianhao
#Mail:          tianhao.luo@hand-china.com
#Version:       1.0
#Date:          2021-03-16
#FileName:      11_15_10.sh
#Description:   This is a test script.
#***********************************************
RETVAR=0

sh_path=/u01/learn/shell/scripts

[ ! -d "$sh_path" ] && {
  mkdir $sh_path -p 
}

Usage() {
  echo "Usage:$0 argv"
  return 1
}

function InstallService() {
  [ 1 -ne $# ]&&{
    Usage
  }
  local RETVAR=0
  echo "start installing ${1}"
  sleep 2;
  [ ! -x "$sh_path/${1}.sh" ] && {
    echo "$sh_path/${1}.sh does not exist or can not be exec"
    return 1
  } || {
    $sh_path/${1}.sh
    return $RETVAR
  }
}

main() {
  PS3="echo pls input the num you want:"

  select var in "Install lamp" "Install lnmp" "exit"
  do
      case "$var" in
          "Install lamp")
              InstallService lamp
              RETVAR=$?
              ;;
          "Install lnmp")
              InstallService lnmp
              RETVAR=$?
              ;;
          "exit")
              echo bye
              return 3
              ;;
          *)
              echo "the num you input must be {1|2|3}"
              echo "Input ERROR"
      esac
  done
  exit $ RETVAR
}

main
[root@localhost shell]# sh 11_15_10.sh 
1) Install lamp
2) Install lnmp
3) exit
echo pls input the num you want:1
start installing lamp
lamp
echo pls input the num you want:2
start installing lnmp
lnmp
echo pls input the num you want:3
bye
[root@localhost shell]# 
posted @ 2021-03-16 00:03  春刀c  阅读(529)  评论(0编辑  收藏  举报