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

2022-05-27 12:00:54

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