范例:生成10个随机数保存于数组中,并找出其最大值和最小值
[root@rocky8 ~]# vim max_min.sh #!/bin/bash # #********************************************************************************************** #Author: Raymond #QQ: 88563128 #Date: 2021-10-22 #FileName: max_min.sh #URL: raymond.blog.csdn.net #Description: The test script #Copyright (C): 2021 All rights reserved #********************************************************************************************* declare -i min max declare -a nums for ((i=0;i<10;i++));do nums[$i]=$RANDOM [ $i -eq 0 ] && min=${nums[0]} && max=${nums[0]} && continue [ ${nums[$i]} -gt $max ] && max=${nums[$i]} && continue [ ${nums[$i]} -lt $min ] && min=${nums[$i]} done echo "All numbers are ${nums[*]}" echo Max is $max echo Min is $min [root@rocky8 ~]# bash max_min.sh All numbers are 11268 31340 1794 24730 32582 4141 21637 25521 22265 12240 Max is 32582 Min is 1794
范例:编写脚本,定义一个数组,数组中的元素对应的值是/var/log目录下所有以.log结尾的文件;统计出其下标为偶数的文件中的行数之和
[root@rocky8 ~]# vim array.sh #!/bin/bash # #********************************************************************************************** #Author: Raymond #QQ: 88563128 #Date: 2021-10-22 #FileName: array.sh #URL: raymond.blog.csdn.net #Description: The test script #Copyright (C): 2021 All rights reserved #********************************************************************************************* declare -a files files=(/var/log/*.log) declare -i lines=0 for i in $(seq 0 $[${#files[*]}-1]); do if [ $[$i%2] -eq 0 ];then let lines+=$(wc -l ${files[$i]} | cut -d' ' -f1) fi done echo "Lines: $lines" [root@rocky8 ~]# bash array.sh Lines: 1311
基于偏移量取字符串
#返回字符串变量var的长度,一个汉字也算一个 ${#var} #返回字符串变量var中从第offset个字符后(不包括第offset个字符)的字符开始,到最后的部分,offset的取值在0 到 ${#var}-1 之间(bash4.2后,允许为负值) ${var:offset} #返回字符串变量var中从第offset个字符后(不包括第offset个字符)的字符开始,长度为number的部分 ${var:offset:number} #取字符串的最右侧几个字符,取字符串的最右侧几个字符, 注意:冒号后必须有一空白字符 ${var: -length} #从最左侧跳过offset字符,一直向右取到距离最右侧lengh个字符之前的内容,即:掐头去尾 ${var:offset:-length} #先从最右侧向左取到length个字符开始,再向右取到距离最右侧offset个字符之间的内容,注意:-length前空格,并且length必须大于offset ${var: -length:-offset}
范例:
[root@rocky8 ~]# alpha=`echo {a..z}|tr -d ' '` [root@rocky8 ~]# echo $alpha abcdefghijklmnopqrstuvwxyz [root@rocky8 ~]# echo ${#alpha} 26 [root@rocky8 ~]# echo ${alpha:10} #跳过前10个 klmnopqrstuvwxyz [root@rocky8 ~]# echo ${alpha:10:6} #跳过前10个取6个 klmnop [root@rocky8 ~]# echo ${alpha:-6} abcdefghijklmnopqrstuvwxyz #-6 前边不加空格不起作用 [root@rocky8 ~]# echo ${alpha: -6} #倒数6个 uvwxyz [root@rocky8 ~]# echo ${alpha: -6:3} #倒数6个中的前3个 uvw [root@rocky8 ~]# echo ${alpha:6:-5} #掐头去尾 ghijklmnopqrstu [root@rocky8 ~]# echo ${alpha: -6:-5} #倒数6个,跳过倒数5个 u
基于模式取子串
#其中word可以是指定的任意字符,自左而右,查找var变量所存储的字符串中,第一次出现的word, 删除字符串开头至第一次出现word字符串(含)之间的所有字符,即懒惰模式,以第一个word为界删左留右 ${var#*word}: #同上,贪婪模式,不同的是,删除的是字符串开头至最后一次由word指定的字符之间的所有内容,即贪婪模式,以最后一个word为界删左留右 ${var##*word}:
范例:
[root@rocky8 ~]# file="var/log/messages" [root@rocky8 ~]# echo ${file#*/} log/messages [root@rocky8 ~]# echo ${file##*/} messages [root@rocky8 ~]# url=http://www.raymond.com/index.html [root@rocky8 ~]# echo ${url#*/} /www.raymond.com/index.html [root@rocky8 ~]# echo ${url##*/} index.html
#其中word可以是指定的任意字符,功能:自右而左,查找var变量所存储的字符串中,第一次出现的word,删除字符串最后一个字符向左(向前)至第一次出现word字符串(含)之间的所有字符,即懒惰模式,以从右向左的第一个word为界删右留左 ${var%word*} #同上,只不过删除字符串最右侧的字符向左至最后一次出现word字符之间的所有字符,即贪婪模式,以从右向左的最后一个word为界删右留左 ${var%%word*}
范例:
[root@rocky8 ~]# echo ${file%/*} var/log [root@rocky8 ~]# echo ${file%%/*} var [root@rocky8 ~]# echo ${url%%/*} http: [root@rocky8 ~]# url=http://www.raymond.com:8080 [root@rocky8 ~]# echo ${url%%:*} http [root@rocky8 ~]# echo ${url##*:} 8080
#查找var所表示的字符串中,第一次被pattern所匹配到的字符串,以substr替换之 ${var/pattern/substr} #查找var所表示的字符串中,所有能被pattern所匹配到的字符串,以substr替换之 ${var//pattern/substr} #查找var所表示的字符串中,行首被pattern所匹配到的字符串,以substr替换之 ${var/#pattern/substr} #查找var所表示的字符串中,行尾被pattern所匹配到的字符串,以substr替换之 ${var/%pattern/substr}
范例:
[root@rocky8 ~]# echo ${url/:/+/} http+///www.raymond.com:8080 [root@rocky8 ~]# echo ${url//:/+/} http+///www.raymond.com+/8080 [root@rocky8 ~]# getent passwd root root:x:0:0:root:/root:/bin/bash [root@rocky8 ~]# line=`getent passwd root` [root@rocky8 ~]# echo $line root:x:0:0:root:/root:/bin/bash [root@rocky8 ~]# echo ${line/#root/admin/} admin/:x:0:0:root:/root:/bin/bash [root@rocky8 ~]# line1=1:`getent passwd root` [root@rocky8 ~]# echo $line1 1:root:x:0:0:root:/root:/bin/bash [root@rocky8 ~]# echo ${line1/#root/admin/} 1:root:x:0:0:root:/root:/bin/bash # #号是以什么开头 [root@rocky8 ~]# echo ${line/%bash/nologin/} root:x:0:0:root:/root:/bin/nologin/ # % 以什么结尾
#删除var表示的字符串中第一次被pattern匹配到的字符串 ${var/pattern} #删除var表示的字符串中所有被pattern匹配到的字符串 ${var//pattern} #删除var表示的字符串中所有以pattern为行首匹配到的字符串 ${var/#pattern} #删除var所表示的字符串中所有以pattern为行尾所匹配到的字符串 ${var/%pattern}
范例:
[root@rocky8 ~]# echo ${line/root/} :x:0:0:root:/root:/bin/bash [root@rocky8 ~]# echo ${line//root/} :x:0:0::/:/bin/bash
#把var中的所有小写字母转换为大写 ${var^^} #把var中的所有大写字母转换为小写 ${var,,}
范例:
[root@rocky8 ~]# echo ${line^^} #^^ 转换成大写 ROOT:X:0:0:ROOT:/ROOT:/BIN/BASH [root@rocky8 ~]# LINE=`echo ${line^^}` [root@rocky8 ~]# echo $LINE ROOT:X:0:0:ROOT:/ROOT:/BIN/BASH [root@rocky8 ~]# echo ${LINE,,} #,, 转换成小写 root:x:0:0:root:/root:/bin/bash
范例:
[root@rocky8 ~]# unset name;cto=${name-'raymond'};echo $cto raymond [root@rocky8 ~]# name="";cto=${name-'raymond'};echo $cto [root@rocky8 ~]# name="boss";cto=${name-'raymond'};echo $cto boss [root@rocky8 ~]# unset name;cto=${name:-'raymond'};echo $cto raymond [root@rocky8 ~]# name="";cto=${name:-'raymond'};echo $cto raymond [root@rocky8 ~]# name="boss";cto=${name:-'raymond'};echo $cto boss
Shell变量一般是无类型的,但是bash Shell提供了declare和typeset两个命令用于指定变量的类型,两个命令是等价的
declare [选项] 变量名 选项: -r 声明或显示只读变量 -i 将变量定义为整型数 -a 将变量定义为数组 -A 将变量定义为关联数组 -f 显示已定义的所有函数名及其内容 -F 仅显示已定义的所有函数名 -x 声明或显示环境变量和函数,相当于export -l 声明变量为小写字母 declare -l var=UPPER -u 声明变量为大写字母 declare -u var=lower
范例:
[root@rocky8 ~]# declare -l name=BOSS [root@rocky8 ~]# echo $name boss [root@rocky8 ~]# declare -u name=boss [root@rocky8 ~]# echo $name BOSS
eval命令将会首先扫描命令行进行所有的置换,然后再执行该命令。该命令适用于那些一次扫描无法实现其功能的变量,该命令对变量进行两次扫描
范例:
[root@rocky8 ~]# echo $name BOSS [root@rocky8 ~]# CMD=whoami [root@rocky8 ~]# echo $CMD whoami [root@rocky8 ~]# eval $CMD #eval 两次扫描,第一次,变量替换,第二次执行替换后的结果 root [root@rocky8 ~]# n=10;for i in {1..$n};do echo $i; done {1..10} [root@rocky8 ~]# n=10;for i in `eval echo {1..$n}`;do echo $i; done 1 2 3 4 5 6 7 8 9 10 [root@rocky8 ~]# i=1 [root@rocky8 ~]# j=a [root@rocky8 ~]# $j$i=hello -bash: a1=hello: command not found [root@rocky8 ~]# eval $j$i=hello [root@rocky8 ~]# echo $j$i a1 [root@rocky8 ~]# echo $a1 hello
如果第一个变量的值是第二个变量的名字,从第一个变量引用第二个变量的值就称为间接变量引用variable1的值是variable2,而variable2又是变量名,variable2的值为value,间接变量引用是指通过variable1获得变量值value的行为
variable1=variable2 variable2=value
bash Shell提供了两种格式实现间接变量引用
#方法1 #变量赋值 eval tempvar=\$$variable1 #显示值 eval echo \$$variable1 eval echo '$'$variable1 #方法2 #变量赋值 tempvar=${!variable1} #显示值 echo ${!variable1}
范例:
[root@rocky8 ~]# x=y [root@rocky8 ~]# y=100 [root@rocky8 ~]# echo $x y [root@rocky8 ~]# eval echo \$$x 100 [root@rocky8 ~]# eval echo $$x 2417x [root@rocky8 ~]# echo $$ 2417 [root@rocky8 ~]# echo ${!x} 100
范例: 批量创建用户
[root@rocky8 ~]# vim eval_createuser.sh #!/bin/bash # #********************************************************************************************** #Author: Raymond #QQ: 88563128 #Date: 2021-10-22 #FileName: eval_createuser.sh #URL: raymond.blog.csdn.net #Description: The test script #Copyright (C): 2021 All rights reserved #********************************************************************************************* n=$# [ $n -eq 0 ] && { echo "Usage: `basename $0` username..." ; exit 2; } for i in `eval echo {1..$n}`;do user=${!i} id $user &> /dev/null && echo $user is exist || { useradd $user; echo $user is created; } done [root@rocky8 ~]# bash eval_createuser.sh tom jack bob tom is created jack is created bob is created