一、自定义变量
declare 声明 shell 变量,若不加上任何参数,则会显示全部的shell变量与函数(与执行set指令的效果相同)。
-a :将后面名为variable 的变量定义成为数组 (array) 类型
-i :将后面名为variable 的变量定义成为整数数字 (integer) 类型
-x :用法不 export 一样,就是将后面的 variable 变成环境变量
-r :将变量设定成为readonly 类型,该变量不可被更改内容,也不能unset
-f :显示函数的内容(不带函数名,就是显示所有函数)
declare -f function_name
二、位置变量
特殊变量 $? $0 $* $@ $#
位置变量 $1 $2 ..... ${10}
$1 $2是取shell脚本后的变量
$0是取shell脚本的名字本身
$*是取一个脚本的所有位置变量
$@也是取一个脚本的所有位置变量,区别在于$*取出的多个值是多个字符串,$@取出的值是一个字符串
$#表示所有位置变量的个数
$$表示当前进程的ID号
三、变量的展开和替换
Syntax |
description |
${var:-value} | 如果变量var没有被定义或为空,就使用默认值value来代替变量var的值,但是不会改变var的值 |
${var:+value} | 如果变量var不为空,就使用默认值value来代替变量var的值,但是不会改变var的值;如果变量var为空,不进行任何替换返回null |
${var:=value} | 如果变量var没有被定义或为空,在返回value的值的同时把值value赋给它 |
${var:?msg} |
若变量已赋值的话,返回var的值;如果变量var的值为空,那么打印msg到标准错误输出并退出脚本 |
${#value} 变量的字符个数(变量的字符个数,并不是变量的个数)
${value:offset}和${value:offset:length}
从变量中提取子串,这里offset和length可以是算术表达式
${value#pattern}和${value##pattern} 去掉value中与pattern相匹配的部分(pattern可以写linux通配符,如*,?)
${value##pattern}
对$value的变量按pattern模式进行匹配(从左向右),将匹配到的最长一个匹配值及其左边的值去掉后返回。又叫最长模式。
${value#pattern}
对$value的变量按pattern模式进行匹配(从左向右),并将匹配到的最短的一个及其左边的值去掉后返回。又叫最短模式。
${value%pattern}和${value%%pattern}
和上面的一样,只是是从value的尾部与pattern相匹配,%与%%的区别与#与##一样
${value/pattern/string}和${value//pattern/string}
进行变量内容的替换,把与pattern匹配的部分替换为string的内容,/只替换第一个匹配字符,//是全部替换
四、数组
声明一个数组:
declare -a Name
赋值方法1:
Name[0]="zhu"
Name[1]="wang"
Name[2]="ding"
Name[6]="sun" #可以这样赋值,这样赋值就会有7个元素,其中3、4、5的值为空
赋值方法2:
Name=("zhu ssui" wang ding sun) #每个元素之间用空格分开,这样赋值就只有4个元素
Name=([0]="zhu"[1]="wang" [2]="ding" [6]="sun") #同赋值方法1
对数组元素的引用:
${Name[index]}
${Name[*]}和${Name[@]} 显示数组中所有元素
某个元素中字符的个数(长度):
${#Name[index]}
${#Name} = ${#Name[0]}
整个数组中非空的元素的个数:
${#Name[*]} 或者 ${#Name[@]}
五、带颜色输出的shell
-e 用来开启echo中的转义
\e 或 \033 来输出Esc符号
设置颜色的格式: \e[背景色;前景色;高亮m
\033[背景色;前景色;高亮m
恢复默认为\e[0m或\033[0m
第一个参数:
其中背景色可以被以下数字替换
0 透明(使用终端颜色),1 高亮 40 黑,41 红, 42 绿, 43 黄, 44 蓝 45 紫, 46 青绿, 47白(灰)
第二个参数:
前景色(也就是字体的颜色)可以被以下数字替换
30 黑 31 红, 32 绿, 33 黄, 34蓝, 35 紫, 36 青绿, 37 白(灰)
第三个参数:
高亮是1,不高亮是0
第四个参数为m:
注意m后面紧跟字符串
参数不一定要写全,可以部分省略的
六、脚本实例
这个脚本主要是用来分发配置文件到各个平台服务上的。它自己会读2个配置文件list-user和list-user2。
[root@localhost distribution]# cat list-user 192.168.1.22 1377 192.158.1.23 178 #就是这种格式,IP地址对应平台名字
#!/bin/bash # my_fun1() { for HOST in `cat list-user | grep $1 | awk '{print $1}'`; do echo "====================================$1=====================================" scp /media/Slamdunk/Resources_Test/$1/Server/cfg/IniFile/* user@$HOST:~/release/cfg/IniFile/ done } #分发函数 my_fun2() { for HOST in `cat list-user2 | grep $1 | awk '{print $1}'`; do echo "====================================$1=====================================" scp /media/Slamdunk/Resources_Test/$1/Server/cfg/IniFile/* user2@$HOST:~/release/cfg/IniFile/ done } declare -a menus #声明一个菜单数组 declare -i index=1 #声明数组索引的起始值 #检测配置文件的平台是否存在 for I in `cat list-user* | awk '{print $2}' | uniq -c | awk '{print $2}'`; do ls /media/Slamdunk/Resources_Test/ | grep $I > /dev/null if [ $? -ne 0 ]; then echo "Wrong Config File!!!" echo "$I platform not exist!!!" exit 1 else menus[index]=$I #将平台名字填入数组中 index=$[$index+1] fi done #显示菜单 echo -en "\e[33;1m" #开启***字体 for ((i=1;i<=$index;i++)); do if [ $(($i%6)) -eq 0 ]; then #每行显示6个 printf "%d)%-15s\t" $i ${menus[i]} #设置字符串的长度为15,加上Tab键可以完成列的对齐 echo else printf "%d)%-15s\t" $i ${menus[i]} fi done echo -e "\e[0m" #关闭颜色显示 read -p "please input platform name: " PLAT #所有平台都分发 if [ $PLAT = 'all' ];then for FILE in 'list-user' 'list-user2'; do for F_PLAT in `cat $FILE | awk '{print $2}' | uniq -c | awk '{print $2}'`; do if [ $FILE = 'list-user' ]; then my_fun1 $F_PLAT else my_fun2 $F_PLAT fi done done exit 0 fi #按输入的平台进行分发 cat list-user | grep $PLAT > /dev/null if [ $? -eq 0 ]; then my_fun1 $PLAT else cat list-user2 | grep $PLAT > /dev/null if [ $? -eq 0 ]; then my_fun2 $PLAT else echo "Please Input Corrent Platform Name. Thank You." exit 1 fi fi
脚本中,检查配置文件那边用到了数组,显示菜单那边用到了格式化输出和颜色输出。执行效果如下:
下面这个脚本是用用来解密配置文件(用到了变量的展开):
for I in `diff /tmp/RecordDBCfg.xml /tmp/RecordDBCfg.xml.bak | awk -F ['>''"''<'] '{if ($8 ~ /^lmOf/) print $4"-"$8; else print "=";}'`; do if [ $I = '=' ]; then echo "=================" else echo ${I%-*} `~/tools/dbdecode ${I#*-}` fi done
现在先进行步骤分解,首先看看diff里面的输出:
再看awk后的输出:
awk的主要作用就是将id和密文取出来,接下来就是变量的展开了。
${I%-*} 就是去掉$I中“-”后面的部分,只留下id
${I#*-} 就是去掉$I中“-”前面的部分,只留下密文,然后进行解密