高級變量包含三個部分
1、變量擴展
2、命令替換
3、算術擴展
在Bash Shell中,$算符會觸發到上述三種擴展,基本形式如下:
基本型 擴展種類 例子
${變量名稱} 變量擴展 ${filename}
$(命令) 命令替換 $(ls /)
$((算術式)) 算術擴展 $((5+3))
變量存在表示變量有值(包含空)
一、 變量擴展:測試存在性及空值
測試變量“存在與否”的基本用法
${待測變量-默認值}
如果待測變量有定義(包括為空),則傳回待測變量默認值,如果無定義,則傳回-后的默認值。
a=yang a=
b=${a-'hello'}
echo $b
因為變量a有存在,所以$b值為yang,如果a存在,但為空,那么$b值為空。如果a不存在,$b為hello
變量分為兩種狀態,1 存在(包括為空) 2 不存在
${待測變量:-默認值}
如果待測變量存在,則傳回待測變量默認值,如果不存在或為空,則傳回:-后的默認值。
a=yang a=
b=${a:-'hello'}
echo $b
因為變量a存在,所以$b值為yang,如果a為空或不存在,$b的值就為:-后的hello
總結:
如果變量擴展條件式只有- 則只做變量存在性的判斷。
使用:- 則除了做變量是否存在,還會判斷變量是否為空
一句話:多了個“:”,就要同時測試存在性及空值兩種情況。
[ -n ${A:-} ] && set -v
[]是測試條件的語法,-n測試其后接的變量為空,若非空,傳回真值(長度不為0為真,-z長度為0為真)。
${待測變量:=默認值}
如果待測變量不存在或為空,就把待測變量值設為:=后的默認值。若存在,則設為待測變量值。
a=yang
b=${a:='hello'}
echo $b
因為變量a存在,所以$b值為yang,如果a為空或不存在,$b的值就為:=后的hello
b=${a:-'hello'}和b=${a:='hello'}看上去好像是一樣的,但是:-是當變量a為空或者不存在的時候,其后的值hello為變量b的值,a依舊是空或不存在。:=是當變量a為空或不存在的時候,其后的值hello為變量b的值,並且默認為變量a的值(相當於給a賦了一個值)。
${待測變量:?提示信息}
若變量不存在或為空值,則顯示變量名稱和:?后的提示信息,並立即停止執行腳本。
目的:確保變量值一定存在,否則不執行腳本。
#!/bin/bash
fn=${1:?'錯誤,請提供要刪除目錄的名稱'} 對傳入的第一個參數做檢查,若未空,顯示提示信息,並停止腳本。
echo '你要刪除的目錄指令是:'
echo "rm -rf ~/$fn"
測試變量的"存在性"
{待測變量:+真值}
若變量存在,且不為空,則傳回“真值”,否則傳回空值。
a=123
b=${a:+'true'}
echo $b
因為a存在,且值非空,所以$b為true,如果a不存在或a為空,那么$b值為空。
小結:
: 空 測空值
- 負向 測不存在
= 設值 給空值變量設一個默認值
? 有問題 檢查條件是否完備再來執行吧
+ 正向 測試存在
二、變量擴展:取字符串切片、字符串長度
字符串的第一個字符,編號為0,右鄰的字符編號,依次增加1.接下來介紹如如何字符串的某一部分以及如何取得字符串長度
取字符串切片
${變量:位置起點} 位置起點等同於下邊的編號。
a="hello,world"
b=${a:3}
echo $b
由第4個字符開始,到結束。$b值為lo,world
${變量:位置起點:長度}
a="hello,world"
b=${a:3:5}
echo $b
由第4個字符開始,共5個字符。$b的值為lo,wo
取部分位置參數
${@:n} n為正整數,為位置起點到最后
!/bin/bash
echo $0
echo ${@:2} 除了命令本身,從第2個字符(命令本身為0,編號為3)到最后
./script.sh 12 23 34 45 返回值為23 34 45
${@:n:m} n、m為正整數,n是起始字符,m是長度
!/bin/bash
echo $0
echo ${@:2:4} 長度為4
./script.sh 12 23 34 45 56 67 78 返回值為23 34 45 56
計算字符串長度
${#變量名稱} 傳回變量值的字符串長度
[root@Shell ~]# cat 1.sh
#!/bin/bash
#
A='/etc/passwd'
echo ${#A}
[root@Shell ~]# bash 1.sh
11
[root@Shell ~]#
${#數組[@]} 取得數組元素個數
${#數組[*]} 取得數組元素個數
三、變量擴展:對比樣式
這里說的"對比樣式",目的是想截取變量值(字符串)的某一部分。做法是將符合樣式的部分字符串刪除或取代。
由字符串前面對比,刪除相符者
由前邊(最左開始),對比變量值,刪除最短相符合的字符串。
${變量#樣式}
a="/usr/sbin/ntpdate"
b=${a#/*/}
echo $b
/*/代表,凡一對/之間有字符串者,對比符合,那$b值為sbin/ntpdate
由前邊(最左開始),對比變量值,刪除最長相符合的字符串。
${變量##樣式}
a="/usr/sbin/ntpdate"
b=${a##/*/}
echo $b
/*/代表,凡一對/之間有字符串者,對比符合,那$b值為ntpdate
由字符串后面對比,刪除相符者
由后邊(最右開始),對比變量值,刪除最短相符合的字符串。
${變量%樣式}
a="/usr/sbin/ntpdate"
b=${a%/*}
echo $b
/*代表,凡一對/之間有字符串者,對比符合,那$b值為/usr/sbin
由后邊(最右開始),對比變量值,刪除最長相符合的字符串。
${變量%%樣式}
a="/usr/sbin/ntpdate" a="www.baidu.com"
b=${a%%/*} b=${a%%.*}
echo $b echo $b 此時 $b為www
/*代表,凡一對/之間有字符串者,對比符合,那$b值為空
小結:
語法 用途
${變量#樣式} 由前邊對比、刪最短的
${變量##樣式} 由前邊對比、刪最長的
${變量%樣式} 由后邊對比、刪最短的
${變量%%樣式} 由后邊對比、刪最長的
取代或刪除部分字符串
只替換第一個對比符號的字符串(如果刪除,替換字符處為空)
${變量/樣式/替換字符串}
a="root:x:0:0:root:/root:/bin/bash"
b=${a/:/,}
echo $b
$b值為root,x:0:0:root:/root:/bin/bash
替換所有對比符合的字符串(如果刪除,替換字符處為空)
${變量//樣式/替換字符串}
a="root:x:0:0:root:/root:/bin/bash"
b=${a//:/,}
echo $b
$b值為root,x,0,0,root,/root,/bin/bash
b=${a/#s /} 刪除以s開頭的行以空格結尾
b=${a/%s /} 刪除以s結尾的行
四、變量擴展:取變量名稱列表、數組索引列表
取變量名稱列表
${!開頭字符串@} 或${!開頭字符串*}
echo ${!x@} 或${!x*} 以x開頭的變量名稱。
a1=11
a2=dfds
b=sfs
echo ${!a@} 值為a1、a2
取數組索引列表
${!數組變量[@]} 或${!數組變量[*]}
[root@Shell ~]# cat 1.sh
#!/bin/bash
#
a=(one two three four five)
for i in "${!a[@]}"
do
echo "第$i個字符串為${a[$i]}"
done
[root@Shell ~]# bash 1.sh
第0個字符串為one
第1個字符串為two
第2個字符串為three
第3個字符串為four
第4個字符串為five
[root@Shell ~]#
五、命令替換
這里的命令替換指的是把命令執行后的標准輸出放入變量中,有兩種寫法:
新式寫法:變量名稱=$(命令)
舊式寫法:變量名稱=`命令`
舊式寫法的引號為反引號,一般位於Tab鍵上方。
[root@Shell ~]# ls /home/
lost+found nagios xguest
[root@Shell ~]# cat 1.sh
#!/bin/bash
#
a=$(ls /home)
for f in $a
do
echo $f
done
[root@Shell ~]# bash 1.sh
lost+found
nagios
xguest
[root@Shell ~]#
IFS是指定分隔符,默認是空白或Tab
六、算術擴展
如果a=8+4 b=$a echo $b 輸出結果肯定為8+4 ,因為bash shell 把任何存儲在變量中的值,皆視為以字符組成的字符串。
算術擴展的語法:$((算術式))
a=3+4
b=$a
echo $b
輸出則為7
七、單引號、雙引號、反引號的區別
單引號字符串的限制:
1、單引號里的任何字符都會原樣輸出,單引號字符串中的變量是無效的;
2、單引號字串中不能出現單引號(對單引號使用轉義符后也不行)。
雙引號的優點:
1、雙引號里可以有變量
2、雙引號里可以出現轉義字符
反引號
反引號括起來的東西是一個執行的命令
date是一個可以查看日期的命令
PWD是內部變量,echo $PWD顯示當前路徑
我們看一下使用不同的符號會有什么效果
1、美元符號$在單、雙引號的表現,單引號中的$將保留它的字面意思,雙引號中的$將發生變量引用
[root@Shell ~]# echo '$PWD'
$PWD
[root@Shell ~]# echo "$PWD"
/root
2、反斜杠\在單、雙引號中的表現,單引號中\將保留它的字面意思,雙引號中的\轉義后邊的字符(失去特殊意義)
[root@Shell ~]# echo '\$PWD'
\$PWD
[root@Shell ~]# echo "\$PWD"
$PWD
3、反引號與其它兩種符號不同,反引號包圍起來的字符串將被運行,取其結果。
[root@Shell ~]# echo 'date'
date
[root@Shell ~]# echo "date"
date
[root@Shell ~]# echo `date`
Fri May 1 12:39:21 CST 2015
注:反引號中的date被當成命令執行,包含的正是命令從輸出信息。
總結:
當需要一個字符串的時候,使用單引號;
當內部包含變量的時候,使用雙引號;
當鋪捉命令輸出的時候,用反引號;