15 SHELL脚本编程进阶

SHELL脚本编程进阶

  • 循环 for;while
  • 信号捕捉
  • 函数 判断操作系统版本的函数;判断Y|N的函数
  • 数组
  • 高级字符串操作
  • 高级变量
  • expect

for–适用于数字和序列

常用便利列表

[root@CentOS8 ~]#sum=0;for i in {1..100};do let sum+=i;done;echo $sum
5050

[root@CentOS8 ~]#for i in {1..10};do useradd user$i;passwd --stdin centos;passwd -e;echo user$i is created ;done

[root@CentOS8 ~]#for i in {1..10};do userdel -r user$i;done

判断/var/目录下所有文件的类型

[root@CentOS8 script52]#vim for_filetype.sh 

  1 #!/bin/bash
  2 #判断/var/目录下所有文件的类型
  3 for i in $(find /var) ;do  \\find 查看所有文件
  4         if [ -b $i ];then
  5                 echo "$i is  block device!"
  6         elif [ -c $i ] ;then
  7                 echo "$i is  character device!"
  8         elif [ -f $i ];then
  9                 echo "$i is General document!"
 10         elif [ -h $i ];then
 11                 echo "$i is Symbol Link File!"
 12         elif [ -p $i ];then
 13                 echo "$i is Pipe files!"
 14         elif [ -S $i ];then
 15                 echo "$i is socket file!"
 16         elif [ -d $i ];then
 17                 echo "$i is directory!"
 18         else
 19                 echo "file is not exist!"                                                 
 20         fi
 21 done
 22 exit 0

添加10个用户user1-user10,密码为8位随机字符

[root@CentOS8 script52]#vim for_user1.sh 

  1 #!/bin/bash
  2 #
  3 #********************************************************************
  4 for ((i=1;i<=10;i++));do
  5         NAME=user$i
  6         useradd $NAME
  7         PASS="$(tr -cd [[:alnum:]\!_#@] < /dev/urandom | head -c 8)"  \\获取八位随机密码
  8         echo $PASS |  passwd --stdin $NAME &> /dev/null                                          
  9         echo "$NAME is created!Passwd is $PASS"
 10 done
 11 exit 0

/etc/rc.d/rc3.d目录下分别有多个以K开头和以S开头的文件;分别读取每个文件,以K开头的输出为文件加stop,以S开头的输出为文件名加start,如K34filename stop。
S66filename start

[root@CentOS8 script52]#vim for_filerename.sh

  1 #!/bin/bash
  2 #
  3 DIR=/data/etc_rc
  4 cd $DIR
  5 for FILE in *;do
  6         BYTE=`echo $FILE | sed -rn 's#(^K|S).*#\1#p'`
  7         if [ "$BYTE" = K  ];then
  8                 echo "$FILE stop"
  9         elif [ "$BYTE" = S  ];then
 10                 echo "$FILE start"                                              
 11         else
 12                 continue
 13         fi
 14 done
 15 exit 0
 [root@CentOS8 script52]#bash for_filerename.sh
K1 stop
K10 stop
K2 stop
K3 stop
K4 stop
K5 stop
K6 stop
K7 stop
K8 stop
K9 stop
S1 start
S10 start
S2 start
S3 start
S4 start
S5 start
S6 start
S7 start
S8 start
S9 start
[root@CentOS8 etc_rc]#ls
K1  K10  K2  K3  K4  K5  K6  K7  K8  K9  S1  S10  S2  S3  S4  S5  S6  S7  S8  S9

编写脚本,提示输入正整数n的值,计算1+2+…+n的总和

[root@CentOS8 script52]#vim for_sum.sh

  1 #!/bin/bash
  2 #
  3 read -p "Please input a positive integer: " NUM
  4 for ((i=1;i<=NUM;i++));do
  5         let sum+=i
  6 done
  7 echo "sum is $sum"                                

计算n以内所有能被3整除的整数之和

[root@CentOS8 script52]#vim for_%3.sh

  1 #!/bin/bash
  2 #
  3 read -p "Please input a positive integer:" n
  4 for ((i=1;i<=n;i++));do                                                                       
  5         if [ $[$i%3] -eq 0 ];then
  6                 let sum+=i
  7         fi
  8 done
  9 echo "sum is $sum"

编写脚本,提示请输入网络地址,如192.168.0.0,判断网段中主机在线状态

[root@CentOS8 script52]#vim online.sh 

  1 #!/bin/bash
  2 #
  3 #********************************************************************
  4 read -p "请输入网络地址,如192.168.0.0。IP=" IP
  5 net=`echo $IP | sed -nr 's#([0-9.]{4}[0-9]+)\..*#\1#p'`
  6 for ((i=0;i<=255;i++));do
  7         for ((j=1;j<255;j++));do
  8         ip=$net.$i.$j                                                                         
  9         ping -w1 -c1 $ip &> /dev/null && echo "$ip is up!" || echo "$ip is down!"
 10         done
 11 done

在/testdir目录下创建10个html文件,文件名格式为数字N(从1到10)加随机8个字;如:1AbCdeFgH.html。

[root@CentOS8 script52]#vim for_testdir.sh

  1 #!/bin/bash
  2 #
  3 DIR=/data/test
  4 cd $DIR
  5 for ((n=1;n<=10;n++));do                                         
  6         file=`echo "$n$(tr -cd [:alpha:] < /dev/random | head -c 8).html"`
  7         touch $file
  8         echo "$file is establish"       
  9 done

[root@CentOS8 script52]#bash for_testdir.sh
1gexyqPgY.html is establish
2IMqQyByt.html is establish
3bKYIBXTl.html is establish
4aKVWHsJK.html is establish
5osgRApSP.html is establish
6wkInQiwN.html is establish
7UiCLVdia.html is establish
8ydgykIqU.html is establish
9nzpHFWFI.html is establish
10ZhgBnEgB.html is establish

[root@CentOS8 test]#ls
10ZhgBnEgB.html  2018-12  2019-04  2019-08         3bKYIBXTl.html  7UiCLVdia.html
1gexyqPgY.html   2019-01  2019-05  2019-09         4aKVWHsJK.html  8ydgykIqU.html
2018-10          2019-02  2019-06  2019-10         5osgRApSP.html  9nzpHFWFI.html
2018-11          2019-03  2019-07  2IMqQyByt.html  6wkInQiwN.html
[root@CentOS8 script52]#vim for_peach.sh

  1 #!/bin/bash
  2 read -p "please input a positive integer:" n
  3 sum=1
  4 for((i=1;i<n;i++));do                         
  5         let sum=$[$[$sum+1]*2]
  6 done
  7 echo "The number of peach is $sum!"

程序和变量相分离–批量创建用户,且让用户开机修改密码

[root@CentOS8 script52]#vim for_user.sh

  1 #!/bin/bash
  2 #
  3 #********************************************************************
  4 #Author:                yanyi99
  5 #QQ:                    691538172
  6 #Date:                  2019-10-29
  7 #FileName:             for_user.sh
  8 #URL:                   http://www..com
  9 #Description:          The test script
 10 #Copyright (C):         2019 All rights reserved
 11 #********************************************************************
 12 read -p "please input the user you wanted:" NAME  \\变量输入方式一
 13 NAME="yanyi dsbhz"  \\变量输入方式二
 14 for i in $NAME ;do
 15 for i in `cat user.txt`;do  \\变量输入方式三
 16         useradd $i
 17         echo 123456 | passwd --stdin $i &> /dev/null
 18         passwd -e $i &> /dev/null
 19         echo $i is created!
 20 done

for批量改文件(rename)

sed-->一个一个文件修改(慢100万文件一个个处理)
rename-->批量修改同一个后缀的所有文件(快相同后缀的一次处理)
[root@CentOS8 script52]#vim for_rename.sh

 1 #!/bin/bash
 11 #********************************************************************
 12 DIR=/data/test
 13 cd $DIR
 14 for i in * ;do  //逐个修改文件,速度慢
 15         NAME=`echo $i | sed -rn 's#(.*)\.(.*)#\1#p'`
 16         SUFFIX=`echo $i | sed -rn 's#(.*)\.(.*)#\2#p'`           
 17         mv $i $NAME.jpg
 18         echo "$i修改完毕"
 19 done
[root@CentOS8 script52]#vim for_rename.sh
 1 #!/bin/bash
 21 DIR=/data/test
 22 cd $DIR
 23 for SUFFIX in `ls | sed -rn 's#(.*)(\..*)#\2#p' | sort -u`;do  //根据后缀不同批量修改后缀相同的文件
 24         rename $SUFFIX .log *$SUFFIX
 25         echo "$SUFFIX 修改完毕"               

9*9乘法表

[root@CentOS8 script52]#vim nine.sh

  1 #!/bin/bash
 11 #********************************************************************
 12 for ((i=1;i<=9;i++));do
 13         for((j=1;j<=i;j++));do
 14                 #let sum=$[j*i]
 15                 #echo -n -e "${j}x${i}=$sum\t"
 16                 echo -e "${j}x${i}=$[j*i]\t\c"                                
 17         done
 18         echo
 19 done
[root@CentOS8 script52]#bash nine.sh 
1x1=1	
1x2=2	2x2=4	
1x3=3	2x3=6	3x3=9	
1x4=4	2x4=8	3x4=12	4x4=16	
1x5=5	2x5=10	3x5=15	4x5=20	5x5=25	
1x6=6	2x6=12	3x6=18	4x6=24	5x6=30	6x6=36	
1x7=7	2x7=14	3x7=21	4x7=28	5x7=35	6x7=42	7x7=49	
1x8=8	2x8=16	3x8=24	4x8=32	5x8=40	6x8=48	7x8=56	8x8=64	
1x9=9	2x9=18	3x9=27	4x9=36	5x9=45	6x9=54	7x9=63	8x9=72	9x9=81	
[root@CentOS8 script52]#vim nine2.sh
 1 #!/bin/bash
 11 #********************************************************************
 12 for i in {1..9};do
 13         for j in `seq $i`;do
 14                 echo -e -n "${j}x${i}=$[i*j]\t"                               
 15         done
 16         echo
 17 done
[root@CentOS8 script52]#bash nine2.sh
1x1=1	
1x2=2	2x2=4	
1x3=3	2x3=6	3x3=9	
1x4=4	2x4=8	3x4=12	4x4=16	
1x5=5	2x5=10	3x5=15	4x5=20	5x5=25	
1x6=6	2x6=12	3x6=18	4x6=24	5x6=30	6x6=36	
1x7=7	2x7=14	3x7=21	4x7=28	5x7=35	6x7=42	7x7=49	
1x8=8	2x8=16	3x8=24	4x8=32	5x8=40	6x8=48	7x8=56	8x8=64	
1x9=9	2x9=18	3x9=27	4x9=36	5x9=45	6x9=54	7x9=63	8x9=72	9x9=81

文件创建和移动(面试题)

要求将目录YYYY-MM-DD/中所有文件,移动到YYYY-MM/DD/下

1 yyyy-mm-dd10.sh 创建YYYY-MM-DD,当前日期一年前365天到目前共365个目录,里面有10个文件,$RANDOM.log   date -d '-1 day' +%F

[root@CentOS8 script52]#vim file_build.sh
  1 #!/bin/bash
  2 #********************************************************************
  3 DIR=/data/test
  4 cd $DIR
  5 for i in {1..365};do
  6         NEWDIR=`date -d "-$i day" +%F`
  7         mkdir $NEWDIR
  8         cd $NEWDIR
  9         for j in {1..10};do
 10                 touch $RANDOM.log
 11         done
 12         cd $DIR
 13 done
 14 echo task completion
 15 echo -e "\a" 
 
 2 移动到YYYY-MM/DD/下

 [root@CentOS8 script52]#vim file_cd.sh

  1 #!/bin/bash
  2 #*******************************************************************
  3 DIR=/data/test
  4 cd $DIR
  5 for i in * ;do
  6         PDIR=`echo $i | sed -nr 's#(.*)-(.*)#\1#p'`
  7         SUBDIR=`echo $i | sed -nr 's#(.*)-(.*)#\2#p'`
  8         [ -d $PDIR/$SUBDIR ] || mkdir -p $PDIR/$SUBDIR &> /dev/null
  9         mv $i/* $PDIR/$SUBDIR                                                 
 10         mv $i /tmp
 11 done
 12 echo task completion
 13 echo -e "\a"

创建圣诞树

[root@CentOS8 script52]#vim print.sh

  1 #!/bin/bash
  2 #
  3 #********************************************************************
  4 #Author:                yanyi99
  5 #QQ:                    691538172
  6 #Date:                  2019-10-28
  7 #FileName:             print.sh
  8 #URL:                   http://www..com
  9 #Description:          The test script
 10 #Copyright (C):         2019 All rights reserved
 11 #********************************************************************
 12 for (( i=1;i<=9;i++ ));do
 13         for (( j=i;j<9;j++  ));do
 14                 echo -e -n " "
 15         done
 16         for (( k=1;k<=2*i-1;k++ ));do                                 
 17                 echo -e -n "\033[1;$[$RANDOM%7+31]m*\033[0m"
 18         done
 19         echo
 20 done
 [root@CentOS8 script52]#bash print.sh 
        *
       ***
      *****
     *******
    *********
   ***********
  *************
 ***************
*****************
[root@CentOS8 script52]#vim print.sh 

  1 #!/bin/bash
  2 #
  3 #********************************************************************
  4 #Author:                yanyi99
  5 #QQ:                    691538172
  6 #Date:                  2019-10-28
  7 #FileName:             print.sh
  8 #URL:                   http://www..com
  9 #Description:          The test script
 10 #Copyright (C):         2019 All rights reserved
 11 #********************************************************************
 12 read -p "请输入行数:" LINE
 13 for (( i=1;i<=$LINE;i++ ));do
 14         for (( j=i;j<$LINE;j++  ));do     
 15                 echo -e -n " "
 16         done
 17         for (( k=1;k<=2*i-1;k++ ));do
 18                 echo -e -n "\033[1;$[$RANDOM%7+31]m*\033[0m"
 19         done
 20         echo
 21 done
[root@CentOS8 script52]#vim print.sh 

  1 #!/bin/bash
  2 #
  3 #********************************************************************
  4 #Author:                yanyi99
  5 #QQ:                    691538172
  6 #Date:                  2019-10-28
  7 #FileName:             print.sh
  8 #URL:                   http://www..com
  9 #Description:          The test script
 10 #Copyright (C):         2019 All rights reserved
 11 #********************************************************************
 12 read -p "请输入行数:" LINE
 13 for (( i=1;i<=$LINE;i++ ));do
 14         for (( j=i;j<$LINE;j++  ));do
 15                 echo -e -n " "
 16         done
 17         for (( k=1;k<=2*i-1;k++ ));do
 18                 echo -e -n "\033[$[$RANDOM%7+41];$[$RANDOM%7+31]m*\033[0m"                 
 19         done
 20         echo
 21 done

国际棋盘

[root@CentOS8 script52]#vim Chess.sh

  1 #!/bin/bash
  2 #********************************************************************
  3 #Author:                yanyi99
  4 #QQ:                    691538172
  5 #Date:                  2019-10-28
  6 #FileName:             Chess.sh
  7 #URL:   i               http://www..com
  8 #Description:          The test script
  9 #Copyright (C):         2019 All rights reserved
 10 #********************************************************************
 11 for (( i=1;i<=8;i++ ));do
 12         if [ $[i%2] -eq 0 ];then
 13                 for((j=1;j<=8;j++));do
 14                         if [ $[j%2] -eq 0 ];then
 15                                 echo -e -n "\033[43;31m  \033[0m"
 16                         else
 17                                 echo -e -n "\033[42;31m  \033[0m"
 18                         fi
 19                 done
 20         else
 21                 for((j=1;j<=8;j++));do
 22                         if [ $[j%2] -eq 1 ];then
 23                                 echo -e -n "\033[43;31m  \033[0m"
 24                         else
 25                                 echo -e -n "\033[42;31m  \033[0m"
 26                         fi
 27                 done
 28         fi                                                            
 29         echo
 30  done
[root@CentOS8 script52]#bash Chess.sh 
##@@##@@##@@##@@
@@##@@##@@##@@##
##@@##@@##@@##@@
@@##@@##@@##@@##
##@@##@@##@@##@@
@@##@@##@@##@@##
##@@##@@##@@##@@
@@##@@##@@##@@##

while–通用更复杂的条件(数字和序列)

[root@CentOS8 script52]#vim online_while.sh 
  1 #!/bin/bash
  2 #
  3 #********************************************************************
  4 read -p "请输入网络地址,如192.168.0.0。IP=" IP
  5 net=`echo $IP | sed -nr 's#([0-9.]{4}[0-9]+)\..*#\1#p'`
  6 i=52
  7 sum_up=0
  8 sum_down=0
  9 while [ $i -le 255 ];do
 10         j=1
 11         while [ $j -le 254 ];do
 12                 ip=$net.$i.$j
 13                 if ping -w1 -c1 $ip &> /dev/null ;then
 14                         let sum_up++
 15                         echo "$ip is up!"
 16                 else
 17                         let sum_down++
 18                         echo "$ip is down!"
 19                 fi
 20                 let j++
 21         done
 22         let i++
 23 done
 24 echo "the up is $up"                                    
 25 echo "the down is $down"
[root@CentOS8 script52]#vim while_random.sh

  1 #!/bin/bash
  2 i=1
  3 while [ $i -le 10 ] ;do
  4         num=`echo $RANDOM`
  5         echo "$num"
  6         if [ $i -eq 1 ];then
  7                 max=$num
  8                 min=$num
  9         else
 10                 if [ "$num" -ge "$max" ];then
 11                         max=$num
 12                 fi
 13                 if [ "$num" -le "$min" ];then              
 14                         min=$num
 15                 fi
 16         fi
 17         let i++
 18 done
 19 echo "MAX is $max"
 20 echo "MIN is $min"
 [root@CentOS8 script52]#bash while_random.sh
12578
31908
31856
15067
11518
29211
5642
11943
10538
141
MAX is 31908
MIN is 141

随机生成10以内的数字,实现猜字游戏,提示比较大小,相等则退出

[root@CentOS8 script52]#vim numbergame.sh

  1 #!/bin/bash
  2 #
  3 num=`echo $[$RANDOM%10]`
  4 until false;do
  5         read -p "please input a number(0-10):" n
  6                 if [ "$n" -eq "$num" ];then
  7                         echo "number is $n"
  8                         break
  9                 elif [ "$n" -ge "$num" ];then
 10                         echo "$n > num"
 11                 else
 12                         echo "$n < num"         
 13                 fi
 14 done

用两个以上的数字为参数,显示其中的最大值和最小值

[root@CentOS8 script52]#vim number_daxiao.sh

  1 #!/bin/bash
  2 #
  3 #********************************************************************
  4 max=$1
  5 min=$1
  6 until [ $# -eq 0 ];do
  7         if [ $1 -gt $max ];then
  8                 max=$1
  9         fi
 10         if [ $1 -lt $min ];then
 11                 min=$1                  
 12         fi
 13         shift
 14 done
 15 echo "MIN is $min"
 16 echo "MAX is $max"

计算奇数和;偶数和

[root@CentOS8 script52]#vim while_sum.sh 
  1 #!/bin/bash                                                     
  3 sum=0
  4 i=0
  5 while [ $i -le 100 ];do
  6         let sum+=i
  7         let i++
  8 done
  9 echo sum=$sum
 10 su=0
 11 j=1
 12 while [ $j -le 100 ];do
 13         let su+=j
 14         let j+=2
 15 done
 16 echo su=$su
 19 s=0
 20 k=0
 21 while [ $k -le 100 ];do
 22         let s+=k
 23         let k+=2
 24 done
 25 echo s=$s
 28 m=0
 29 q=0
 30 n=0
 31 while [ $n -le 100 ];do
 32         if [ $[n%2] -eq 1 ];then  \\注意此处求余数写法$[n%2]
 33                 let m+=n
 34         else
 35                 let q+=n
 36         fi
 37         let n++
 38 done

9*9口诀–while

[root@CentOS8 script52]#vim while_nine.sh
  1 #!/bin/bash
  2 #
  3 #*******************************************************************
  4 i=1
  5 while [ $i -le 9 ];do
  6         j=1
  7         while [ $j -le $i ];do
  8                 echo -e -n "${j}x${i}=$[j*i]\t"
  9                 let j++
 10         done
 11         echo
 12         let i++                                       
 13 done

[root@CentOS8 script52]#bash while_nine.sh
1x1=1	
1x2=2	2x2=4	
1x3=3	2x3=6	3x3=9	
1x4=4	2x4=8	3x4=12	4x4=16	
1x5=5	2x5=10	3x5=15	4x5=20	5x5=25	
1x6=6	2x6=12	3x6=18	4x6=24	5x6=30	6x6=36	
1x7=7	2x7=14	3x7=21	4x7=28	5x7=35	6x7=42	7x7=49	
1x8=8	2x8=16	3x8=24	4x8=32	5x8=40	6x8=48	7x8=56	8x8=64	
1x9=9	2x9=18	3x9=27	4x9=36	5x9=45	6x9=54	7x9=63	8x9=72	9x9=81	

监控httpd服务(while死循环)

[root@CentOS8 script52]#vim while_httpd1.sh

  1 #!/bin/bash
  2 #
  3 while true ;do
  4         if ! killall -0 httpd &>  /dev/null; then  \\判断状态是否正常,正常返回echo $? 为0,!0就是假,所以进入下一个循环;返回的值!0,!!0就是就是真,执行重启服务,在进入下一个循环。
  5                 systemctl restart httpd &> /dev/null
  6                 echo "At `date +%F_%T` httpd is restarted" >> /var/log/httpd.log
  7         fi
  8         sleep 5                                                                           
  9 done

[root@CentOS8 ~]#systemctl stop httpd.service  \\停止服务
[root@CentOS8 ~]#killall -0 httpd  \\查看httpd状态是否停止;在另一个终端执行脚本,脚本死循环不退出
httpd: no process found
[root@CentOS8 ~]#killall -0 httpd  \\查看状态,正常
[root@CentOS8 ~]#systemctl stop httpd.service  \\再次停止服务
[root@CentOS8 ~]#killall -0 httpd  \\查看状态,异常
httpd: no process found
[root@CentOS8 ~]#killall -0 httpd  \\脚本死循环,过几秒再次查看状态,状态正常

[root@CentOS8 wang]#tail -F /var/log/httpd.log  \\追踪查看httpd日志
At 2019-10-29_12:33:33 httpd is restarted
At 2019-10-29_12:37:29 httpd is restarted
At 2019-10-29_12:39:01 httpd is restarted

curl 测试httpd服务:进程活跃判断服务和协议判断服务

[root@CentOS8 script52]#vim while_httpd2.sh

  1 #!/bin/bash
  2 #
  3 while : ;do                                                                               
  4         #if ! killall -0 httpd &>  /dev/null; then
  5         if ! curl --connect-timeout 1 -m 1 192.168.52.8 &> /dev/null;then  \\判断网页是否可以访问;正常echo $? 为0,!0就是假,进行下一个循环;异常echo $?为!0,!!0就是真,就执行重启服务。
  6                 systemctl restart httpd &> /dev/null
  7                 echo "At `date +%F_%T` httpd is restarted" >> /var/log/httpd.log
  8         fi
  9         sleep 5
 10 done

[root@CentOS8 ~]#cd /var/www/html/
[root@CentOS8 html]#ls
[root@CentOS8 html]#touch index.html \\建好测试的网页:welcome to yanyi99

[root@CentOS8 html]#systemctl stop httpd.service  \\停止服务
[root@CentOS8 html]#curl --connect-timeout 1 -m 1 192.168.52.8  \\查看网页是否可以访问,异常
curl: (7) Failed to connect to 192.168.52.8 port 80: Connection refused
[root@CentOS8 html]#curl --connect-timeout 1 -m 1 192.168.52.8  \\查看网页是否可以访问,正常
welcome to yanyi99
[root@CentOS8 html]#systemctl stop httpd.service  \\停止服务
[root@CentOS8 html]#curl --connect-timeout 1 -m 1 192.168.52.8  \\查看网页是否可以访问,异常
curl: (7) Failed to connect to 192.168.52.8 port 80: Connection refused
[root@CentOS8 html]#curl --connect-timeout 1 -m 1 192.168.52.8  \\查看网页是否可以访问,正常
welcome to yanyi99

[root@CentOS8 wang]#tail -F /var/log/httpd.log  \\追踪查看httpd日志
At 2019-10-29_12:53:20 httpd is restarted
At 2019-10-29_12:53:35 httpd is restarted
At 2019-10-29_12:53:40 httpd is restarted

continue break exit

continue–满足条件跳过此次循环进入下一次循环;不满足执行指令

continue:提前结束第N层的本轮循环,而直接进入下一轮判断;n个循环嵌套,最外层是n层,最内层为第1层。

[root@CentOS8 script52]#vim continue.sh

  1 #!/bin/bash
  2 #
  3 #********************************************************************
  4 for ((i=0;i<10;i++));do
  5         if [ $i -eq 5  ];then
  6                 continue     \\当i=5时,满足条件,直接跳过此次循环进入下一个本轮循环,不执行echo $?         
  7         fi
  8         echo $i
  9 done
 10 echo break                   \\此命令执行
[root@CentOS8 script52]#bash continue.sh
0
1
2
3
4
6
7
8
9
break

continue 1 默认是1,指的是continue所在的循环

[root@CentOS8 script52]#vim for_continue1.sh

  1 #!/bin/bash
  2 #
  3 #********************************************************************
  4 for ((i=1;i<10;i++ ));do
  5         for((j=0;j<10;j++));do
  6                 if [ $j -eq 5 ];then
  7                         continue   \\默认是1,也就是所在的循环
  8                 fi
  9                 echo -n $j
 10         done
 11         echo
 12 done
 [root@CentOS8 script52]#bash for_continue1.sh  \\i循环是2循环,相当在每次i循环里,跳过了j5循环,每次打印012346789。
012346789
012346789
012346789
012346789
012346789
012346789
012346789
012346789
012346789

continue 2 指的是倒数第二个循环

[root@CentOS8 script52]#vim for_continue2.sh

  1 #!/bin/bash
  2 #********************************************************************
  3 for ((i=1;i<10;i++ ));do
  4         for((j=0;j<10;j++));do
  5                 if [ $j -eq 5 ];then
  6                         continue 2   \\默认是1,2指的是本循环的上层循环,当条件满足时,跳过后续的本轮循环进入下轮上层循环。
  7                 fi
  8                 echo -n "$j"                                
  9         done
 10 done
[root@CentOS8 script52]#bash for_continue2.sh  \\i循环是2循环,相当在j=5时,跳过了j循环后续的命令执行,直接进入下轮i循环,每次打印01234
012340123401234012340123401234012340123401234

脚本实现两个文本合并

[root@CentOS8 script52]#vim bing.sh
  1 #!/bin/bash
  2 #
  3 declare -a a
  4 declare -a b
  5 a=(1 2 3 4 5)
  6 b=(a b c d e)
  7 i=0
  8 while [ $i -le 4 ];do
  9         j=0
 10         while [ $j -le 4 ];do
 11                 if [ $i -eq $j ];then
 12                         echo ${a[$i]} 
 13                         echo ${b[$i]}          
 14                         let i++
 15                         continue 2
 16                 else
 17                         let j++
 18                         continue
 19                 fi
 20         done
 21 done
 [root@CentOS8 script52]#bash bing.sh
1
a
2
b
3
c
4
d
5
e

[root@CentOS8 script52]#vim bing.sh
  1 #!/bin/bash
  2 #
  3 declare -a a
  4 declare -a b
  5 a=(1 2 3 4 5)
  6 b=(a b c d e)
  7 i=0
  8 while [ $i -le 4 ];do
  9         j=0
 10         while [ $j -le 4 ];do
 11                 if [ $i -eq $j ];then
 12                         echo "${a[$i]}  ${b[$i]}"       
 13                         let i++
 14                         continue 2
 15                 else
 16                         let j++
 17                         continue        
 18                 fi
 19         done
 20 done
 [root@CentOS8 script52]#bash bing.sh
1  a
2  b
3  c
4  d
5  e

break—满足条件直接退出此循环,接着执行下面的命令,不满足执行指令继续循环,直到满足条件就退出

break:提前结束第N层循环,最内层为第1层

[root@CentOS8 script52]#vim break.sh

  1 #!/bin/bash
  2 #
  3 #********************************************************************
  4 for ((i=0;i<10;i++));do
  5         if [ $i -eq 5  ];then
  6                 break         \\当i=5时,满足条件,直接退出此循环,接着执行下面的命令echo break。
  7         fi
  8         echo $i
  9 done
 10 echo break                   \\此命令执行
[root@CentOS8 script52]#bash break.sh 
0
1
2
3
4
break

break 1

[root@CentOS8 script52]#vim for_break1.com

  1 #!/bin/bash
  2 #
  3 #********************************************************************
  4 for ((i=1;i<10;i++ ));do
  5         for((j=0;j<10;j++));do
  6                 if [ $j -eq 5 ];then
  7                         break                        
  8                 fi
  9                 echo -n $j
 10         done
 11         echo
 12 done
[root@CentOS8 script52]#bash for_break1.com
01234
01234
01234
01234
01234
01234
01234
01234
01234

break 2

[root@CentOS8 script52]#vim for_break2.com

  1 #!/bin/bash
  2 #********************************************************************
  3 for ((i=1;i<10;i++ ));do
  4         for((j=0;j<10;j++));do
  5                 if [ $j -eq 5 ];then                                                      
  6                         break 2
  7                 fi
  8                 echo  "$j"
  9         done
 10 done
[root@CentOS8 script52]#bash for_break2.com
0
1
2
3
4

exit直接退出脚本

[root@CentOS8 script52]#vim exit.sh

  1 #!/bin/bash
  2 #
  3 #********************************************************************
  4 for ((i=0;i<10;i++));do
  5         if [ $i -eq 5  ];then
  6                 exit   \\直接退出脚本
  7         fi
  8         echo $i
  9 done
 10 echo break             \\此命令不执行
[root@CentOS8 script52]#bash exit.sh
0
1
2
3
4

until–用法同while(与while判断相反,CONDITION为假时执行)

shift

用于将参量列表 list 左移指定次数,缺省为左移一次。

参量列表 list 一旦被移动,最左端的那个参数就从列表中删除。while循环遍历位置参量列表时,常用到 shift

[root@CentOS8 script52]#vim shift_user.sh

  1 #!/bin/bash
  2 #
  3 #********************************************************************
  4 while [ "$1" ];do
  5         useradd $1
  6         echo $1 is created!
  7         shift                                          
  8 done
[root@CentOS8 script52]#bash shi_user.sh   q w e p
q is created!
w is created!
e is created!
p is created!
[root@CentOS8 script52]#getent shadow |tail -n4
q:!!:18198:0:99999:7:::
w:!!:18198:0:99999:7:::
e:!!:18198:0:99999:7:::
p:!!:18198:0:99999:7:::
[root@CentOS8 script52]#vim shift_doit.sh

  1 #!/bin/bash
  2 while [ $# -gt 0 ];do
  3         echo $*
  4         shift
  5 done                                     
[root@CentOS8 script52]#bash shift_doit.sh a b c d
a b c d
b c d
c d
d

while read遍历文件的每一行

while read line; do
循环体
done < /PATH/FROM/SOMEFILE  \\依次读取/PATH/FROM/SOMEFILE文件中的每一行,且将行赋值给变量line
[root@centos8 script39]#echo a b c  | read i j k;echo i=$i;echo j=$j;echo k=$k  \\管道符|的作用,开启子进程,"echo a b c  | read i j k;是一个整体,在子进程"而"echo i=$i;echo j=$j;echo k=$k"在父进程
i=
j=
k=
[root@centos8 script39]#echo a b c  | { read i j k;echo i=$i;echo j=$j;echo k=$k; }  \\所有命令在一个进程,注意最后的分号,必须有
i=a
j=b
k=c
[root@centos8 script39]#echo a b c  | ( read i j k;echo i=$i;echo j=$j;echo k=$k;)
i=a
j=b
k=c
[root@centos8 script39]#echo a b c  | while read i j k; do echo i=$i;echo j=$j;echo k=$k;done
i=a
j=b
k=c
[root@centos8 script39]#echo a b c  | while read i ; do echo i=$i ;done
i=a b c
[root@centos8 script39]#unset i j k; echo "  a b c"  | while read i j k; do echo i=$i;echo j=$j;echo k=$k;done  \\空格不起作用,再多的空格也是分割变量
i=a
j=b
k=c

硬盘使用率报警

[root@CentOS8 script52]#vim read_device_warning.sh

  1 #!/bin/bash
  2 #
  3 #********************************************************************
  4 WARNING=5
  5 df | sed -nr '/\/dev\/nvme/s#(^[^[:blank:]]+) .* ([0-9]+)%.*#\1  \2#p' | while read DEV USE;do
  6         if [ $USE -ge $WARNING ];then                                                                      
  7                 echo $DEV will be full,use:$USE%
  8         fi
  9 done
[root@CentOS8 script52]#df
Filesystem     1K-blocks    Used Available Use% Mounted on
devtmpfs          910220       0    910220   0% /dev
tmpfs             924716       0    924716   0% /dev/shm
tmpfs             924716   17696    907020   2% /run
tmpfs             924716       0    924716   0% /sys/fs/cgroup
/dev/nvme0n1p2 104806400 5269352  99537048   6% /
/dev/nvme0n1p5  52403200  400956  52002244   1% /data
/dev/nvme0n1p1    999320  131292    799216  15% /boot
tmpfs             184940      16    184924   1% /run/user/42
tmpfs             184940       4    184936   1% /run/user/0
[root@CentOS8 script52]#bash read_device_warning.sh
/dev/nvme0n1p2 will be full,use:6%
/dev/nvme0n1p1 will be full,use:15%

拒绝 dos攻击

[root@CentOS8 ~]#iptables -A INPUT -s IPADDR -j REJECT  \\禁止此IP访问主机:防火墙机制

创建用户

[root@CentOS8 script52]#vim read_while_user.sh

  1 #!/bin/bash
  2 #
  3 while read USER PASSWD ;do
  4         useradd $USER                                                                      
  5         echo $PASSWD | passwd --stdin $USER &> /dev/null
  6         echo "$USER is created"
  7 done < user.txt
[root@CentOS8 script52]#vim user.txt

  1 liukang  yanyi11
  2 liushen liushen
  3 sunshuxia sunshuxia
  4 liutiechang liutiechang   

select循环与菜单

select variable in list;do
    循环体命令
done
1、select 循环主要用于创建菜单,按数字顺序排列的菜单项将显示在标准错误上,并显示 PS3 提示符,等待用户输入
2、用户输入菜单列表中的某个数字,执行相应的命令
3、用户输入被保存在内置变量 REPLY 中
4、select 是个无限循环,因此要记住用 break 命令退出循环,或用 exit 命令终止脚本。也可以按 ctrl+c 退出循环
5、select 经常和 case 联合使用
6、与 for 循环类似,可以省略 in list, 此时使用位置参量

选择执行脚本

[root@CentOS8 script52]#vim select.sh

  1 #!/bin/bash
  2 #
  3 #********************************************************************
  4 sum=0
  5 PS3="请输入(1-6):"
  6 select MENU in 北京烤鸭 盐焗鸡 狗不理 粉蒸肉 龙虾 点菜结束;do
  7 case $REPLY in
  8 1)
  9         echo $MENU price is100
 10         let sum+=100
 11         ;;
 12 2)
 13         echo $MENU price is 88                                                             
 14         let sum+=88
 15         ;;
 16 3)
 17         echo $MENU price is 77
 18         let sum+=77
 19         ;;
 20 4)
 21         echo $MENU price is 66
 22         let sum+=66
 23         ;;
 24 5)
 25         echo $MENU price is 200 
 26         let sum+=200
 27         ;;
 28 6)
 29         echo "点菜结束,退出"
 30         break
 31         ;;
 32 *)
 33         echo "点菜错误,重新选择"
 34         ;;
 35 esac
 36 done
 37 echo sum=$sum

函数function

查看系统大版本

[root@CentOS8 script52]#vim os.sh 

  1 #!/bin/bash
  2 #
  3 #********************************************************************
  4 os(){
  5         os_version=`sed -r 's#.* ([0-9]+)\..*#\1#' /etc/centos-release`
  6         if [ $os_version -eq 6 ];then
  7                 echo "os_version is 6"
  8         elif [ $os_version -eq 7 ];then
  9                 echo "os_version is 7"
 10         elif [ $os_version -eq 8 ];then
 11                 echo "os_version is 8"
 12         else
 13                 echo "os_version is none"
 14         fi
 15 }
 16 os
 [root@CentOS8 script52]#. os.sh 
 os_version is 8

当前系统eth0的IP地址

[root@CentOS8 script52]#vim eth0ip.sh

  1 #!/bin/bash
  2 #
  3 #********************************************************************
  4 eth0ip(){
  5         eth0_ip=`ifconfig eth0|sed -nr '2s@[^0-9]+([.0-9]{7,15}).*@\1@p'`
  6                 echo "eth0_ip = $eth0_ip"
  7 }
  8 eth0ip      

编写函数,实现打印绿色OK和红色FAILED

[root@CentOS8 script52]#vim red_or_green.sh

  1 #!/bin/bash
  2 #
  4 OK_red(){
  5         echo -e "\033[1;32m[ OK ]\033[0m"
  6 }
  7 FAILD_green(){
  8         echo -e "\033[1;31m[ FAILD ]\033[0m"
  9 }
 10 OK_red
 11 FAILD_green
 [root@CentOS8 script52]#. red_or_green.sh
 [ OK ]
 [ FAILD ]

编写函数,实现判断是否无位置参数,如无参数,提示错误

[root@CentOS8 script52]#vim args.sh

  1 #!/bin/bash
  2 #
  3 args(){
  4         if [ $# -eq 0 ];then
  5                 echo "please give a parameter!"
  6         fi
  7 }
  8 args $1  

函数递归

函数直接或者间接调用自身
注意递归层数

阶乘

[root@CentOS8 script52]#vim functions 

  1 #!/bin/bash
  2 fact (){
  3         while [ -n "$1" ];do
  4         if [ $1 -eq 1 ];then      
  5                 echo 1
  6         else
  7                 echo $[`fact $[$1-1]`*$1]
  8         fi
  9         shift
 10         done
 11 }
[root@CentOS8 script52]#vim func1.sh 
  1 #!/bin/bash
 12 . functions
 13 fact $*        
[root@CentOS8 script52]#bash func1.sh 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 
1
2
6
24
120
720
5040
40320
362880
3628800
39916800
479001600
6227020800
87178291200
1307674368000
20922789888000
355687428096000
6402373705728000
121645100408832000
2432902008176640000

自己调用自己:死循环

[root@CentOS8 script52]#vim endless_loop.sh

  1 #!/bin/bash
  2 echo $$
  3 #sleep 2               
  4 ./endless_loop.sh   \\调用自己,必须写清除此脚本的完整路劲
[root@CentOS8 script52]#vim endless_loop.sh

  1 #!/bin/bash
  2 echo $$
  3 #sleep 2
  4 /data/script52/endless_loop.sh  \\完整路径

fork 炸弹–>瞬间倾占所有内存资源

fork炸弹是一种恶意程序,它的内部是一个不断在fork进程的限循环,实质是一个简单的递归程序。由于程序是递归的,如果没有任何限制,这会导致这个简单的程序迅速耗尽系统里面的所有资源。

[root@CentOS8 ~]#bomb() { bomb | bomb & }; bomb  \\bomb|bomb&-->表示多个bomb并行生成bomb继续并行,几何式并行
[root@CentOS8 ~]#:(){ :|:& };:

国际棋牌(大)

[root@CentOS8 script52]#vim chess1.sh

  1 #!/bin/bash
  2 #
  3 #********************************************************************
  4 red(){
  5         echo -e "\033[41m                \033[0m\c"        
  6 }
  7 
  8 yel(){
  9         echo -e "\033[43m                \033[0m\c"     
 11 
 12 redyel(){
 13         for ((i=1;i<=8;i++));do
 14                 for ((j=1;j<=4;j++));do
 15                         red;yel
 16                 done
 17                 echo
 18         done
 19 }
 20 
 21 yelred(){
 22         for ((i=1;i<=8;i++));do
 23                 for ((j=1;j<=4;j++));do
 24                         yel;red
 25                 done
 26                 echo
 27        done
 28 }
 29 
 30 for ((n=1;n<=8;n++));do
 31         [ $[$n%2] -eq 1 ] && yelred ||redyel
 32 done

重复的工作用函数定义,放入脚本执行

[root@CentOS8 script52]#declare -F  \\查看函数
[root@CentOS8 script52]#declare -f name  \\查看变量创建过程

约束函数体,只在当前的函数体有效,当函数体结束时,不影响其他脚本|函数调用。
local i=10
函数体内的"$"有特殊含义,需要转移$releasever $basearch

调用:函数只有被调用才会执行

调用:给定函数名
函数名出现的地方,会被自动替换为函数代码

函数的生命周期:被调用时创建,返回时终止

return:返回一个状态数字给调用者,不退出脚本

exit #:不输出状态值,退出脚本

$1 $2 变化的参数在函数里调用

信号捕捉trap

trap '触发指令' 信号
    进程收到系统发出的指定信号后,将执行自定义指令,而不会执行原操作

[root@CentOS8 script52]#vim trap1.sh 
  1 #!/bin/bash
  2 #
  3 trap 'echo ctrl+c' int  \\ 接受触发信号
  4 trap -p  \\列出自定义信号操作
  5 for ((i=1;i<=4;i++));do
  6         echo i=$i
  7         sleep 1 
  8 done 
  9 trap '' int


trap '' 信号
    忽略信号的操作

[root@CentOS8 script52]#vim trap1.sh 
  1 #!/bin/bash
  2 #
  3 trap 'echo ctrl+c' int  \\ 接受触发信号
  4 trap -p  \\列出自定义信号操作
  5 for ((i=1;i<=4;i++));do
  6         echo i=$i
  7         sleep 1 
  8 done 
  9 trap '' int  \\忽略信号
 10 trap -p  \\列出自定义信号操作
 11 for i in {5..10};do
 12         echo i=$i
 13         sleep 1
 14 done       


trap '-' 信号
    恢复原信号的操作

[root@CentOS8 script52]#vim trap1.sh 
  1 #!/bin/bash
  2 #
  3 trap 'echo ctrl+c' int  \\ 接受触发信号
  4 trap -p  \\列出自定义信号操作
  5 for ((i=1;i<=4;i++));do
  6         echo i=$i
  7         sleep 1
  8 done
  9 trap '' int   \\忽略信号
 10 trap -p  \\列出自定义信号操作
 11 for i in {5..10};do
 12         echo i=$i
 13         sleep 1
 14 done
 16 trap '-' int     \\恢复信号 '-'短下划线 '_'错误
 17 trap -p  \\列出自定义信号操作
 18 for i in {11..15};do
 19         echo i=$i
 20         sleep 1
 21 done


trap -p
    列出自定义信号操作


trap finish EXIT
    当脚本退出时,执行finish函数

[root@CentOS8 script52]#vim trap3.sh 
  1 #!/bin/bash                 
  3 finish(){   \\定义finish脚本
  4         echo finish run
  5 }
  6 
  7 trap finish EXIT  \\接受EXIT退出脚本信号
  8 trap -p  \\列出自定义信号操作
  9 for i in {1..10};do
 10         echo i-$i
 11         sleep 1
 12 done

数组

输人若干个数值存入数组中,采用冒泡算法进行升序或降序排序

[root@CentOS8 script52]#vim array_bubble.sh
  1 #!/bin/sh
  2 declare -a rand    \\将输入的数字声明到数组rand
  3 declare -i sub=   \\用于在冒泡循环中当中间值
  4 echo "Please input the numbers you want to sort:"
  5 read -a rand  \\写入数字
  6 for ((i=0;i<${#rand[*]}-1;i++));do  \\冒泡循环外循环次数共数组个数
  7         for ((j=0;j<${#rand[*]}-i-1;j++));do  \\冒泡循环内循环次数一次比一次小1
  8                 if [ ${rand[$j]} -gt ${rand[$j+1]} ];then
  9                         sub=${rand[$j+1]}   \\将min给sub
  10                         rand[$j+1]=${rand[$j]}  \\将max赋值给min
 11                         rand[$j]=$sub  \\将中间值赋值给max=将min赋值给max ;实现min值放在数组前面
 12                 fi
 13         done
 14 done                                     
 15 echo "The numbers have been sorted:${rand[*]}"

实现转置矩阵matrix.sh

[root@CentOS8 script52]#vim array_concert.sh
  1 #!/bin/bash
  2 #
  3 arr=([00]=1 [01]=2 [02]=3 [10]=4 [11]=5 [12]=6 [20]=7 [21]=8 [22]=9)
  4 size=3
  5 echo "before showmatrix"
  6 for((i=0;i<3;i++ ));do
  7         for ((j=0;j<3;j++));do
  8                 echo -e "${arr[$i$j]} \c"
  9         done
 10         echo                        
 11 done
 12 echo "After convert"                                                                              
 13 for((i=0;i<3;i++ ));do
 14         for ((j=0;j<3;j++));do
 15                 echo -e "${arr[$j$i]} \c"
 16         done
 17         echo
 18 done
[root@CentOS8 script52]#bash array_concert.sh
before showmatrix
1 2 3 
4 5 6 
7 8 9 
After convert
1 4 7 
2 5 8 
3 6 9 

打印杨辉三角形

[root@CentOS8 script52]#vim array_yanghuisanjiao.sh

  1 #!/bin/bash
  2 #
  3 read -p "please input the number of lines:" l
  4 declare -a a 
  5 for ((i=1;i<=$l;i++));do
  6         if [ $i -eq 1 ];then
  7                 echo "1"
  8         else
  9                 for ((j=1;j<=i;j++));do
 10                         if [ $j -eq 1 ];then
 11                                 echo  -n "1 "
 12                                 a[$i$j]=1
 13                         elif [ $j -eq $i ];then
 14                                 echo "1"
 15                                 a[$i$j]=1
 16                         else
 17         #                       let a[$i$j]=${a[$[i-1]$[j-1]]}+${a[$[i-1]$[j]]}
 18                                 let a[$i$j]=${a[$[i-1]$[j-1]]}+${a[$[i-1]$[j]]}
 19                                 echo -n -e  "${a[$i$j]} \c"
 20                         fi
 21                 done
 22         fi               
 23 done
[root@CentOS8 script52]#bash array_yanghuisanjiao.sh
please input the number of lines:10
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
变量:存储单个元素的内存空间
数组:存储多个元素的连续的内存空间,相当于多个变量的集合
数组名和索引
    索引:编号从0开始,属于数值索引
    注意:索引可支持使用自定义的格式,而不仅是数值格式,即为关联索引,bash4.0版本之后开始支持
    bash的数组支持稀疏格式(索引不连续)
声明数组:
    declare -a ARRAY_NAME
    declare -A ARRAY_NAME 关联数组
注意:两者不可相互转换

标准数组-赋值

[root@CentOS8 script52]#title[0]=ceo
[root@CentOS8 script52]#title[1]=coo
[root@CentOS8 script52]#title[2]=cto
[root@CentOS8 script52]#echo ${title[0]}
ceo
[root@CentOS8 script52]#echo ${title[1]}
coo
[root@CentOS8 script52]#echo ${title[2]}
cto
[root@CentOS8 script52]#echo ${title[*]}
ceo coo cto
[root@CentOS8 script52]#read -a name
zhao qian sun li
[root@CentOS8 script52]#echo ${name[0]}
zhao
[root@CentOS8 script52]#echo ${name[1]}
qian
[root@CentOS8 script52]#echo ${name[2]}
sun
[root@CentOS8 script52]#echo ${name[3]}
li
[root@CentOS8 script52]#echo ${name[*]}
zhao qian sun li
[root@CentOS8 script52]#title=([0]=co [1]=cd [2]=cf)  \\定义数组
[root@CentOS8 script52]#echo ${title[0]}  \\打印下标0变量
co
[root@CentOS8 script52]#echo ${title[1]}  \\打印下标1变量
cd
[root@CentOS8 script52]#echo ${title[2]}  \\打印下标2变量
cf
[root@CentOS8 script52]#echo ${title[3]}  \\打印下标3变量不存在

[root@CentOS8 script52]#echo ${title[*]}  \\打印数组中所有变量
co cd cf
[root@CentOS8 script52]#echo ${#title[@]}  \\数组中变量的个数
3
[root@CentOS8 script52]#echo ${title[*]:0:1}  \\显示从0开始的第一个
co
[root@CentOS8 script52]#echo ${title[*]:1:1}  \\显示从1开始的第一个变量
cd
[root@CentOS8 script52]#echo ${title[*]:1:2}  \\显示从1开始的第1、2个变量
cd cf
[root@CentOS8 script52]#echo ${title[*]:0:2}  \\显示从0开始的第1、2个变量
co cd
[root@CentOS8 script52]#title[${#title[@]}]=ofo  \\添加新的变量 | ${#title[@]} 下标为原数组变量的个数
[root@CentOS8 script52]#echo ${title[*]}
co cd cf ofo
[root@CentOS8 script52]#echo ${#title[*]}
4
[root@CentOS8 script52]#goods=(car plane ship)
[root@CentOS8 script52]#echo ${goods[0]}
car
[root@CentOS8 script52]#echo ${goods[1]}
plane
[root@CentOS8 script52]#echo ${goods[2]}
ship
[root@CentOS8 script52]#echo ${goods[*]}
car plane ship
[root@CentOS8 script52]#echo ${#goods[*]}
3
[root@CentOS8 script52]#alpha=({a..z})
[root@CentOS8 script52]#echo ${alpha[0]}
a
[root@CentOS8 script52]#echo ${alpha[25]}
z
[root@CentOS8 script52]#echo ${alpha[*]}
a b c d e f g h i j k l m n o p q r s t u v w x y z
[root@CentOS8 script52]#echo ${alpha[@]}
a b c d e f g h i j k l m n o p q r s t u v w x y z
[root@CentOS8 script52]#echo ${#alpha[@]}
26
[root@CentOS8 script52]#num=({1..100..3})
[root@CentOS8 script52]#echo ${num[1]}
4
[root@CentOS8 script52]#echo ${num[0]}
1
[root@CentOS8 script52]#echo ${num[20]}
61
[root@CentOS8 script52]#echo ${num[*]}
1 4 7 10 13 16 19 22 25 28 31 34 37 40 43 46 49 52 55 58 61 64 67 70 73 76 79 82 85 88 91 94 97 100
[root@CentOS8 script52]#echo ${#num[*]}
34
[root@CentOS8 script52]#num[${#num[*]}]=103
[root@CentOS8 script52]#echo ${#num[*]}
35
[root@CentOS8 script52]#echo ${num[*]}
1 4 7 10 13 16 19 22 25 28 31 34 37 40 43 46 49 52 55 58 61 64 67 70 73 76 79 82 85 88 91 94 97 100 103
[root@CentOS8 script52]#num[${#num[*]}]=200
[root@CentOS8 script52]#echo ${num[*]}
1 4 7 10 13 16 19 22 25 28 31 34 37 40 43 46 49 52 55 58 61 64 67 70 73 76 79 82 85 88 91 94 97 100 103 200
[root@CentOS8 script52]#ls
chess1.sh  endless_loop.sh  fork.sh  func1.sh  functions  trap1.sh  trap2.sh  trap3.sh
[root@CentOS8 script52]#ls |wc -l
8
[root@CentOS8 script52]#file=(*.sh)
[root@CentOS8 script52]#echo ${file[@]}
chess1.sh endless_loop.sh fork.sh func1.sh trap1.sh trap2.sh trap3.sh
[root@CentOS8 script52]#echo ${#file[@]}
7
[root@CentOS8 script52]#echo ${file[0]}
chess1.sh

关联数组-赋值

关联数组,必须先声明才能使用

[root@CentOS8 script52]#student=([a]='aaa' [b]='bbb' [c]='ccc')  \\声明标准数组
[root@CentOS8 script52]#echo ${student[a]}
ccc
[root@CentOS8 script52]#echo ${student[b]}
ccc
[root@CentOS8 script52]#echo ${student[c]}
ccc
[root@CentOS8 script52]#echo ${student[*]}
ccc
[root@CentOS8 script52]#echo ${#student[*]}
1
[root@CentOS8 script52]#unset student  \\删除标准数组student
[root@CentOS8 script52]#echo ${student[*]}

[root@CentOS8 script52]#declare -A student=([a]=aa [b]=bb [c]=cc)  \\声明关联数组
[root@CentOS8 script52]#echo ${student[a]}
aa
[root@CentOS8 script52]#echo ${student[b]}
bb
[root@CentOS8 script52]#echo ${student[c]}
cc
[root@CentOS8 script52]#echo ${student[*]}
aa bb cc
[root@CentOS8 script52]#echo ${#student[*]}
3

声明标准变量

[root@CentOS8 script52]#vim Array_max_min.sh
  1 #!/bin/bash
    read -p "Please input a number:" num
  2 declare -a ARR
  3 for (( i=1;i<=num;i++ ));do
  4         ARR[$i]=$RANDOM
  5         if [ $i = 1 ];then
  6                 MAX=${ARR[$i]}
  7                 MIN=${ARR[$i]}
  8         else
  9                 [ "${ARR[$i]}" -gt $MAX ] && MAX=${ARR[$i]}
 10                 [ "${ARR[$i]}" -lt $MIN ] && MIN=${ARR[$i]}
 11         fi
 12 done
 13 echo "Total number is ${#ARR[*]}!"
 14 echo "All random are ${ARR[*]}!"
 15 echo Max number is $MAX!
 16 echo Min number is $MIN!    
 [root@CentOS8 script52]#bash  Array_max_min.sh
Total number is 10!
All random are 20608 9049 12024 12997 21261 9703 27867 15359 31370 2489!
Max number is 31370!
Min number is 2489!

[root@CentOS8 script52]#bash  Array_max_min.sh
Please input a number:100
Total number is 100!
All random are 2388 29427 20562 15256 3739 1096 16472 27061 30539 6111 17309 9734 1118 14320 3643 23138 23164 3092 7920 23791 27429 20641 7757 27145 32100 18359 29677 27389 6089 14330 2363 11570 25759 13284 19893 22913 9509 22321 30319 7291 24330 4343 29341 8748 7642 22186 18321 1592 25072 3131 31020 14387 14702 1465 26514 23866 18935 28342 12058 30704 9072 2473 1003 26041 421 20821 28235 9432 7791 10046 10594 32588 5534 29176 1396 14262 24055 18645 14430 21295 29230 21430 31542 25467 15811 1879 11321 516 9893 19877 23131 16741 29541 3302 7021 20630 23281 23135 21812 553!
Max number is 32588!
Min number is 421!

字符串切片

${#var}:返回字符串变量var的长度

${var:offset}:返回字符串变量var中从第offset个字符后(不包括第offset个字符)的字符开始,到最后的部分,offset的取值在0 到 ${#var}-1 之间(bash4.2后,允许为负值)

${var:offset:number}:返回字符串变量var中从第offset个字符后(不包括第offset个字符)的字符开始,长度为number的部分

${var: -length}:取字符串的最右侧几个字符
注意:冒号后必须有一空白字符

${var:offset:-length}:从最左侧跳过offset字符,一直向右取到距离最右侧lengh个字符之前的内容

${var: -length:-offset}:先从最右侧向左取到length个字符开始,再向右取到距离最右侧offset个字符之间的内容
[root@CentOS8 script52]#echo {a..z}
a b c d e f g h i j k l m n o p q r s t u v w x y z
[root@CentOS8 script52]#echo {a..z}|tr -d ' '
abcdefghijklmnopqrstuvwxyz
[root@CentOS8 script52]#str=`echo {a..z}|tr -d ' '`  \\声明字符串
[root@CentOS8 script52]#echo ${str[0]}
abcdefghijklmnopqrstuvwxyz
[root@CentOS8 script52]#echo ${str[*]}
abcdefghijklmnopqrstuvwxyz
[root@CentOS8 script52]#echo ${#str[*]}  \\字符串等于是一个变量
1
[root@CentOS8 script52]#echo ${#str}  \\字符串长度
26
[root@CentOS8 script52]#echo ${str}
abcdefghijklmnopqrstuvwxyz
[root@CentOS8 script52]#echo ${str:2}  \\显示length=2之后的字符串
cdefghijklmnopqrstuvwxyz
[root@CentOS8 script52]#echo ${str:3}
defghijklmnopqrstuvwxyz
[root@CentOS8 script52]#echo ${str:3:4}  \\显示length=3之后的连续length=4字符串
defg
[root@CentOS8 script52]#echo ${str:4:4}
efgh
[root@CentOS8 script52]#echo ${str: -3}  \\显示倒数length=3的字符串
xyz
[root@CentOS8 script52]#echo ${str:26 -3} \\同上
xyz
[root@CentOS8 script52]#echo ${str: :4}  \\显示length=0之后的连续length=4字符串
abcd
[root@CentOS8 script52]#echo ${str:0:4}  \\显示length=0之后的连续length=4字符串
abcd
****************************************************************************************************
  [root@CentOS8 script52]#echo ${str::0 -5}
  abcdefghijklmnopqrstu
  [root@CentOS8 script52]#echo ${str::1 -5}
  abcdefghijklmnopqrstuv
  [root@CentOS8 script52]#echo ${str::2 -5}
  abcdefghijklmnopqrstuvw
  [root@CentOS8 script52]#echo ${str::3 -5}
  abcdefghijklmnopqrstuvwx
  [root@CentOS8 script52]#echo ${str::4 -5}
  abcdefghijklmnopqrstuvwxy
  [root@CentOS8 script52]#echo ${str::5 -5}

  [root@CentOS8 script52]#echo ${str::6 -5}
  a
  [root@CentOS8 script52]#echo ${str::7 -5}
  ab
  [root@CentOS8 script52]#echo ${str::8 -5}
  abc
  [root@CentOS8 script52]#echo ${str::9 -5}
  abcd
  [root@CentOS8 script52]#echo ${str::25 -5}
  abcdefghijklmnopqrst
  [root@CentOS8 script52]#echo ${str::26 -5}
  abcdefghijklmnopqrstu
****************************************************************************************************
[root@CentOS8 script52]#echo ${str: -4: -3}
w
[root@CentOS8 script52]#echo ${str: -4:-2}
wx
[root@CentOS8 script52]#echo ${str: -4:-1}
wxy
[root@CentOS8 script52]#echo ${str: -4}
wxyz
[root@CentOS8 script52]#echo ${str: -4:0}

[root@CentOS8 script52]#echo ${str: -4:-1}
wxy
[root@CentOS8 script52]#echo ${str: -4:-2}
wx
[root@CentOS8 script52]#echo ${str: -4:-3}
w
[root@CentOS8 script52]#echo ${str: -4:-4}

[root@CentOS8 script52]#echo ${str: -4:-5}
-bash: -5: substring expression < 0
****************************************************************************************************
[root@CentOS8 script52]#echo ${str:4 }
efghijklmnopqrstuvwxyz
[root@CentOS8 script52]#echo ${str:4 -1}
defghijklmnopqrstuvwxyz
[root@CentOS8 script52]#echo ${str:4 -2}
cdefghijklmnopqrstuvwxyz
[root@CentOS8 script52]#echo ${str:4 -3}
bcdefghijklmnopqrstuvwxyz
[root@CentOS8 script52]#echo ${str:4 -4}
abcdefghijklmnopqrstuvwxyz
[root@CentOS8 script52]#echo ${str:4 -5}
z
[root@CentOS8 script52]#echo ${str:4 -6}
yz
[root@CentOS8 script52]#echo ${str:4 -7}
xyz
[root@CentOS8 script52]#echo ${str:4 -8}
wxyz
[root@CentOS8 script52]#echo ${str:4 -26}
efghijklmnopqrstuvwxyz
[root@CentOS8 script52]#echo ${str:4 -27}
defghijklmnopqrstuvwxyz
[root@CentOS8 script52]#echo ${str:4 -30}
abcdefghijklmnopqrstuvwxyz
[root@CentOS8 script52]#echo ${str:4 -31}

[root@CentOS8 script52]#

字符串处理

基于模式取子串
    ${var#*word}:其中word可以是指定的任意字符
    功能:自左而右,查找var变量所存储的字符串中,第一次出现的word, 删除字符串开头至第一次出现word字符串(含)之间的所有字符
    ${var##*word}:同上,贪婪模式,不同的是,删除的是字符串开头至最后一次由word指定的字符之间的所有内容
    ${var%word*}:其中word可以是指定的任意字符
    功能:自右而左,查找var变量所存储的字符串中,第一次出现的word, 删除字符串最后一个字符向左至第一次出现word字符串(含)之间的所有字符
      file="/var/log/messages"
      ${file%/*}: /var/log
    ${var%%word*}:同上,只不过删除字符串最右侧的字符向左至最后一次出现word字符之间的所有字符
查找替换
    ${var/pattern/substr}:查找var所表示的字符串中,第一次被pattern所匹配到的字符串,以substr替换之
    ${var//pattern/substr}: 查找var所表示的字符串中,所有能被pattern所匹配到的字符串,以substr替换之
    ${var/#pattern/substr}:查找var所表示的字符串中,行首被pattern所匹配到的字符串,以substr替换之
    ${var/%pattern/substr}:查找var所表示的字符串中,行尾被pattern所匹配到的字符串,以substr替换之
查找并删除
    ${var/pattern}:删除var表示的字符串中第一次被pattern匹配到的字符串
    ${var//pattern}:删除var表示的字符串中所有被pattern匹配到的字符串
    ${var/#pattern}:删除var表示的字符串中所有以pattern为行首匹配到的字符串
    ${var/%pattern}:删除var所表示的字符串中所有以pattern为行尾所匹配到的字符串
字符大小写转换
    ${var^^}:把var中的所有小写字母转换为大写
    ${var,,}:把var中的所有大写字母转换为小写
[root@CentOS8 script52]#getent passwd root
root:x:0:0:root:/root:/bin/bash
[root@CentOS8 script52]#l=`getent passwd root`
[root@CentOS8 script52]#echo $l
root:x:0:0:root:/root:/bin/bash
[root@CentOS8 script52]#echo ${l#*root}
:x:0:0:root:/root:/bin/bash
[root@CentOS8 script52]#echo ${l##*root}
:/bin/bash
[root@CentOS8 script52]#echo ${l%root*}
root:x:0:0:root:/
[root@CentOS8 script52]#echo ${l%%root*}

[root@CentOS8 script52]#echo ${l/root/bin}
bin:x:0:0:root:/root:/bin/bash
[root@CentOS8 script52]#echo ${l//root/bin}
bin:x:0:0:bin:/bin:/bin/bash
[root@CentOS8 script52]#echo ${l/#root/bin}
bin:x:0:0:root:/root:/bin/bash
[root@CentOS8 script52]#echo ${l/%bash/bin}
root:x:0:0:root:/root:/bin/bin
[root@CentOS8 script52]#echo ${l/%sh/bin}
root:x:0:0:root:/root:/bin/babin
[root@CentOS8 script52]#echo ${l/root}
:x:0:0:root:/root:/bin/bash
[root@CentOS8 script52]#echo ${l//root}
:x:0:0::/:/bin/bash
[root@CentOS8 script52]#echo ${l/#root}
:x:0:0:root:/root:/bin/bash
[root@CentOS8 script52]#echo ${l/%sh}
root:x:0:0:root:/root:/bin/ba
[root@CentOS8 script52]#echo ${l^^}
ROOT:X:0:0:ROOT:/ROOT:/BIN/BASH
[root@CentOS8 script52]#echo ${l^^}|echo ${l,,}
root:x:0:0:root:/root:/bin/bash

字符串取值

[root@CentOS8 script52]#url=http://www.magedu/com:80
[root@CentOS8 script52]#echo $url
http://www.magedu/com:80
[root@CentOS8 script52]#echo ${url##*:}
80
[root@CentOS8 script52]#echo ${url%%:*}
http

高级变量用法-有类型变量

Shell变量一般是无类型的,但是bash Shell提供了declare和typeset两个命令用于指定变量的类型,两个命令是等价的

declare [选项] 变量名

-r 声明或显示只读变量
-i 将变量定义为整型数
-a 将变量定义为数组
-A 将变量定义为关联数组
-f 显示已定义的所有函数名及其内容
-F 仅显示已定义的所有函数名
-x 声明或显示环境变量和函数
-l 声明变量为小写字母 declare –l var=UPPER
-u 声明变量为大写字母 declare –u var=lower

eval

eval命令将会首先扫描命令行进行所有的置换,然后再执行该命令。该命令适用于那些一次扫描无法实现其功能的变量.该命令对变量进行两次扫描。
[root@CentOS8 script52]#CMD=whoami
[root@CentOS8 script52]#echo $CMD
whoami
[root@CentOS8 script52]#eval $CMD
root

[root@CentOS8 script52]#n=10
[root@CentOS8 script52]#echo {1..$n}
{1..10}
[root@CentOS8 script52]#eval echo {1..$n}
1 2 3 4 5 6 7 8 9 10

[root@CentOS8 script52]#title=ceo
[root@CentOS8 script52]#ceo=mage
[root@CentOS8 script52]#echo $title
ceo
[root@CentOS8 script52]#eval echo $title
ceo
[root@CentOS8 script52]#eval echo $$title
1734title
[root@CentOS8 script52]#echo ${!title}
mage

[root@CentOS8 script52]#unset title
[root@CentOS8 script52]#title=$ceo
[root@CentOS8 script52]#ceo=mage
[root@CentOS8 script52]#echo $title
mage

[root@CentOS8 script52]#whoami
root
[root@CentOS8 script52]#eval whoami
root
[root@CentOS8 script52]#echo whoami
whoami
[root@CentOS8 script52]#eval echo whoami
whoami

间接变量引用

如果第一个变量的值是第二个变量的名字,从第一个变量引用第二个变量的值就称为间接变量引用

variable1的值是variable2,而variable2又是变量名, variable2的值为value,间接变量引用是指通过variable1获得变量值value的行为

    variable1=variable2
    variable2=value

bash Shell提供了两种格式实现间接变量引用
    eval tempvar=\$$variable1
    tempvar=${!variable1}
[root@CentOS8 script52]#n=m
[root@CentOS8 script52]#m=1
[root@CentOS8 script52]#echo $m $n
1 m
[root@CentOS8 script52]#n1=${!n}
[root@CentOS8 script52]#echo $n1
1
[root@CentOS8 script52]#eval n2=\$$n
[root@CentOS8 script52]#echo $n2
1

创建临时文件–mktemp

mktemp命令:创建并显示临时文件,可避免冲突
    mktemp [OPTION]... [TEMPLATE]
    TEMPLATE: filenameXXX    X至少要出现三个

OPTION:
    -d 创建临时目录
    -p DIR或--tmpdir=DIR 指明临时文件所存放目录位置

示例:
    mktemp /tmp/testXXX
    tmpdir=`mktemp –d /tmp/testdirXXX`
    mktemp --tmpdir=/testdir testXXXXXX

[root@CentOS8 data]#mktemp -d `date +%F`XXXX
2019-10-31u2VG
[root@CentOS8 data]#ls
2019-10-31u2VG  script52
[root@CentOS8 data]#mktemp -p 2019-10-31u2VG/ -d `date +%F`XXXX
2019-10-31u2VG/2019-10-311mjd
[root@CentOS8 data]#tree
.
├── 2019-10-31u2VG
│   └── 2019-10-311mjd
└── script52

## 安装复制文件–install 类似于cp

install命令:
    install [OPTION]... [-T] SOURCE DEST 单文件
    install [OPTION]... SOURCE... DIRECTORY
    install [OPTION]... -t DIRECTORY SOURCE...
    install [OPTION]... -d DIRECTORY...创建空目录

选项:
    -m MODE,默认755
    -o OWNER
    -g GROUP
    
示例:
    install -m 700 -o wang -g admins srcfile desfile
    install –m 770 –d /testdir/installdir

[root@CentOS8 data]#install -m 770 -o yanyi -g yanyi -d yanyi
[root@CentOS8 data]#ll
total 0
drwxrwx--- 2 yanyi yanyi   6 Oct 31 23:50 yanyi
[root@CentOS8 data]#mkdir sp_yanyi
[root@CentOS8 data]#install -m 770 -o yanyi -g yanyi  script52/* sp_yanyi
[root@CentOS8 data]#ll
total 0
drwxr-xr-x 2 root  root  166 Oct 31 23:51 sp_yanyi
drwxrwx--- 2 yanyi yanyi   6 Oct 31 23:50 yanyi
[root@CentOS8 data]#cd sp_yanyi/
[root@CentOS8 sp_yanyi]#ll
total 36
-rwxrwx--- 1 yanyi yanyi 388 Oct 31 23:51 Array_max_min.sh
-rwxrwx--- 1 yanyi yanyi 537 Oct 31 23:51 chess1.sh
-rwxrwx--- 1 yanyi yanyi  60 Oct 31 23:51 endless_loop.sh
-rwxrwx--- 1 yanyi yanyi  31 Oct 31 23:51 fork.sh
-rwxrwx--- 1 yanyi yanyi 355 Oct 31 23:51 func1.sh
-rwxrwx--- 1 yanyi yanyi 130 Oct 31 23:51 functions
-rwxrwx--- 1 yanyi yanyi 230 Oct 31 23:51 trap1.sh
-rwxrwx--- 1 yanyi yanyi 298 Oct 31 23:51 trap2.sh
-rwxrwx--- 1 yanyi yanyi 434 Oct 31 23:51 trap3.sh
[root@CentOS8 sp_yanyi]#cd ../script52/
[root@CentOS8 script52]#ll
total 36
-rw-r--r-- 1 root root 388 Oct 31 20:42 Array_max_min.sh
-rw-r--r-- 1 root root 537 Oct 31 18:09 chess1.sh
-rwxr-xr-x 1 root root  60 Oct 31 17:35 endless_loop.sh
-rw-r--r-- 1 root root  31 Oct 31 17:39 fork.sh
-rw-r--r-- 1 root root 355 Oct 31 17:21 func1.sh
-rw-r--r-- 1 root root 130 Oct 31 17:24 functions
-rw-r--r-- 1 root root 230 Oct 31 19:38 trap1.sh
-rw-r--r-- 1 root root 298 Oct 31 19:14 trap2.sh
-rw-r--r-- 1 root root 434 Oct 31 19:34 trap3.sh

expect介绍

    expect 是由Don Libes基于Tcl( Tool Command Language )语言开发的,主要应用于自动化交互式操作的场景,借助 expect 处理交互的命令,可以将交互过程如: ssh登录, ftp登录等写在一个脚本上,使之自动化完成。尤其适用于需要对多台服务器执行相同操作的环境中,可以大大提高系统管理人员的工作效率。

expect 语法:
    expect [选项] [ -c cmds ] [ [ -[f|b] ] cmdfile ] [ args ]

选项
    -c: 从命令行执行expect脚本,默认expect是交互地执行的
          示例: expect -c 'expect' "\n" {send "pressed enter\n"}

    -d: 可以输出输出调试信息
          示例: expect -d ssh.exp

expect中相关命令
    spawn 启动新的进程
    expect 从进程接收字符串
    send 用于向进程发送字符串
    interact 允许用户交互
    exp_continue 匹配多个字符串在执行动作后加此命令

! ! ! 注意:远程操作主机时,设置超时时间要长,可能会因为超时时间设置太短,导致不能远程连接

expect命令,非交互式命令,远程登录

[root@CentOS8 script52]#vim expect2
  1 #!/usr/bin/expect
  2 set ip 172.20.52.7
  3 set user root
  4 #set password 123456
  5 set timeout 1000      \\超时时长:刚开始设置的时间是10,但是虚拟机慢,所以需要设置时间长一些。
  6 spawn ssh $user@$ip
  7 expect {
  8         "yes/no" { send "yes\n";exp_continue }
  9         "password" { send "123456\n" }
 10 }
 11 interact

expect命令,非交互式命令,远程复制

[root@CentOS8 script52]#vim expect1
  1 #!/bin/expect
  2 set timeout 1000               
  3 spawn scp /etc/fstab root@192.168.52.6:/data
  4 expect {
  5         "yes/no" { send "yes\n";exp_continue }
  6         "password" { send "123456\n" }
  7 }
  8 expect eof

expect命令,非交互式命令,远程删除。

[root@CentOS8 script52]#vim expect3
  1 #!/bin/expect
  2 set timeout 1000
  3 spawn ssh 192.168.52.6 rm -f /data/fstab
  4 expect {
  5         "yes/no" { send "yes\n";exp_continue }
  6         "password" { send "123456\n" }            
  7 }
  8 expect eof
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值