『忘了再學』Shell基礎 — 21、變量的測試與內容置換

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