• 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	passwd:$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:
     $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]# 
    
  • 相关阅读:
    css滑动门技术02
    ASP.NET2.0中创建自定义配置节处理程序(声明性模型)
    怎样看到ASP.NET从ASPX产生的代码?
    PetShop 4.0 详解之六(PetShop表示层设计)
    如何让Office 2003通过正版验证
    在windows 2003中安装mysql5
    Agile PLM 界面操作变慢优化
    Agile PLM 数据库密码修改
    Agile PLM 文件服务器报错解决
    pyautogui
  • 原文地址:https://www.cnblogs.com/tianhao-luo/p/14540955.html
Copyright © 2020-2023  润新知