1、什麼是變數的測試與內容置換
我們之前說過,在Shell中,一個變數未定義,和一個變數為空值的輸出效果是一樣的。
# 先直接輸出一個未定義的變數y
[root@Lyl ~]# echo $y
# 再定義變數y為空值,並輸出變數y
[root@Lyl ~]# y=""
[root@Lyl ~]# echo $y
[root@Lyl ~]#
其結果都是沒有任何顯示。
前邊在說set
命令的時候說過,執行set -u
命令後,如果一個變數不存在,則會報錯。如果變數為空,則會顯示空。
# 先直接輸出一個未定義的變數x,結果會報錯。
[root@Lyl ~]# echo $x
-bash: x: unbound variable
# 再定義一個空值y,結果就顯示為空。
[root@Lyl ~]# y=""
[root@Lyl ~]# echo $y
[root@Lyl ~]#
所以通過set -u
可以讓我們分清楚Shell中的一個變數是未定義的還是有空值的。
但是人執行命令看提示,是可以區分變數未定義和空值的情況。那如何讓Shell程式來判斷,一個Shell變數是否存在還是有空值,還是有值。(人肉眼能看到的,不見得程式能識別)
當然我們可以識別提示,並根據提示內容做判斷來區分,也是很麻煩的。
Shell覺得我們面對上面的情況會頻率很高,所以Shell幫我們準備了判斷上述情況的表示式。
我們先來看一個變數的測試與內容置換的例子,如下:
變數置換方式 | 變數y沒有設定(未定義) | 變數y為空值 | 變數y設定值 |
---|---|---|---|
x=${y-新值} |
x=新值 |
x為空值 |
x=$y |
說明:
x=${y-新值}
的意思是,通過${y-新值}
表示式,來判斷變數x的值是什麼。如果變數y的值未定義,則變數x的值等於新值;
如果變數y的值是空,則變數x的值也為空(其實就是
x=$y
);如果變數y有值,則變數x的值等於變數y的值。
這個變數的測試,是測試的變數y是否有值,無值,還是未定義。
然後再把結果賦值給變數x。
同理通過變數x的值,也可以判斷變數y的情況是什麼。
2、變數的測試與內容置換
變數置換方式 | 變數y沒有設定(未定義) | 變數y為空值 | 變數y設定值 |
---|---|---|---|
x=${y-新值} |
x=新值 |
x為空值 |
x=$y |
x=${y:-新值} |
x=新值 |
x=新值 |
x=$y |
x=${y+新值} |
x為空值 |
x=新值 |
x=新值 |
x=${y:+新值} |
x為空值 |
x為空值 |
x=新值 |
x=${y=新值} |
x=新值 y=新值 |
x為空值 y值不變 |
x=$y y值不變 |
x=${y:=新值} |
x=新值 y=新值 |
x=新值 y=新值 |
x=$y y值不變 |
x=${y?新值} |
新值輸出到標準錯誤輸出(就是螢幕) | x為空值 |
x=$y |
x=${y:?新值} |
新值輸出到標準錯誤輸出 | 新值輸出到標準錯誤輸出 | x=$y |
說明:
- 如果大括號內沒有
:
,則變數y是為空,還是沒有設定,處理方法是不同的;
如果大括號內有:
,則變數y不論是為空,還是沒有沒有設定,處理方法是一樣的。 - 如果大括號內是
-
或+
,則在改變變數x值的時候,變數y是不改變的;
如果大括號內是=
,則在改變變數x值的同時,變數y的值也會改變。 - 如果大括號內是
?
,則當變數y不存在或為空時,會把“新值”當成報錯輸出到螢幕上。
3、示例
例1:
# 情況1:有一個變數y,未被定義
# 進行測試
[root@Lyl ~]# x=${y-new}
# 因為變數y不存在,所以x=new
[root@Lyl ~]# echo $x
new
# 檢視變數y,但是變數y還是不存在的
[root@Lyl ~]# echo $y
[root@Lyl ~]#
# 情況2:變數y為空
# 定義變數y為空
[root@Lyl ~]# y=""
# 進行測試
[root@Lyl ~]# x=${y-new}
# 變數x和變數y值都是空
[root@Lyl ~]# echo $x
[root@Lyl ~]# echo $y
[root@Lyl ~]#
# 情況3:變數y有值
# 給變數y賦值
[root@Lyl ~]# y=old
# 進行測試
[root@Lyl ~]# x=${y-new}
# 變數x和變數y的值都是old
[root@Lyl ~]# echo $x
old
[root@Lyl ~]# echo $y
old
[root@Lyl ~]#
例2:
# =號的練習
# 情況1:有一個變數y,未被定義
# 進行測試
[root@Lyl ~]# x=${y:=new}
# 變數x和變數y的值都是new
[root@Lyl ~]# echo $x
new
[root@Lyl ~]# echo $y
new
# 注意:
# 一旦使用“=”號,那麼變數y和變數x都會同時進行處理,
# 而不像例子1中只改變變數x的值。
# 情況2:變數y為空
# 定義變數y為空
[root@Lyl ~]# y=""
# 進行測試
[root@Lyl ~]# x=${y:=new}
# 變數x和變數y的值都是new
[root@Lyl ~]# echo $x
new
[root@Lyl ~]# echo $y
new
# 注意;
# 一旦在大括號中使用":",那麼變數y為空或者不設定,處理方式都是一樣的了。
# 情況3:變數y有值
# 給變數y賦值
[root@Lyl ~]# y=old
# 進行測試
[root@Lyl ~]# x=${y:=new}
# 變數x和變數y的值都是old
[root@Lyl ~]# echo $x
old
[root@Lyl ~]# echo $y
old
例3:
# ?號的練習
# 情況1:有一個變數y,未被定義
# 進行測試
# 會把值"new"輸出到螢幕上。
[root@Lyl ~]# x=${y?new}
-bash: y: new
# 情況2:變數y為空
# 定義變數y為空
[root@Lyl ~]# y=""
# 進行測試
[root@Lyl ~]# x=${y?new}
# 變數x和變數y值都是空
[root@Lyl ~]# echo $x
[root@Lyl ~]# echo $y
[root@Lyl ~]#
# 情況3:變數y有值
# 給變數y賦值
[root@Lyl ~]# y=old
# 進行測試
[root@Lyl ~]# x=${y?new}
# 變數x和變數y的值都是old
[root@Lyl ~]# echo $x
old
[root@Lyl ~]# echo $y
old