一、自定義變量
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中“-”前面的部分,只留下密文,然後進行解密