bash 中的 :=、=、:-、-、=?、?、:+、+
來源 https://www.cnblogs.com/fhefh/archive/2011/04/22/2024750.html
變量替換和變量默認值設置是緊密相關的,至少從概念出發是如此。
參數擴張是將類似於變量的參數用它的值來替換。例如以“echo $VAR”的形式調用一個簡單的變量。此外還有更多的特性可以訪問。這個句法還包含一些沒有擴展的特性,雖然這些特性自身很有意義。首先,這類特性執行默認變量賦值。使用這些特性時,整個表達式需要用花括號括起來。
: ${VAR:=”some default”}
這些代碼開始的冒號是一個正確執行非活動任務的shell命令。在這個句法中,它僅僅擴展了行中緊隨其后的所有參數。本例中,只要是要在花括號內擴展參數值。
本行ongoing冒號中的參數是最有趣的部分;它是用花括號起來的一些邏輯的參數擴展。:=句法表示VAR變量將會和“some defalut”字符串進行比較。
在這個表達式中,如果變量VAR還沒有被設置,那么“:=”之后表達式的值將被賦給它,這個值可能是一個數字,一個字符串,或者是另外一個變量。
系統中的腳步可能需要將多個變量設置成默認值。程序員可以在一行中給多個變量設置默認值,而不是編碼一組變量替換,這樣也使得代碼更加緊湊、易讀。下面的例子包含了程序員需要執行的各種替換操作。第一個默認值是一個顯示的串,第二個是一個顯示的整數,第三個是一個已定義的變量。
: ${VAR:=”some default”} ${VAR2:=42} ${VAR3:=$LOGNAME}
這幾個變量替換類型和前例中的:=句法類似。因為不同替換類型的句法都是相同的,不過它們的意義卻略有不同,可能很容易混淆。在大多數情況下,代碼中執行替換句法的地方,這些替換僅僅用某個值替換了變量,但是並沒有設置變量,也就是說變量並沒有被真正賦值。下面句法類型的定義在所有的shell聯機資料中找到的,但是這些說明通常不是很清楚。
:=句法
在這種替換中,使用和前例中相同的:=句法來設置默認值。
username=””
echo “${username:=$LOGNAME}”
在使用“:=”進行比較時,username變量已經被定義了,但是它的值為空。因此,這里對echo命令使用了變量LOGNAME的值,即設置變量username的值為LOGNAME的值。
有了這個特殊的句法,只有當變量username已被定義,而且有一個實際的非空值時,變量username才會被設置為變量LOGNAME的值。
和前例的主要不同是使用活動命令(echo)而不是被動的冒號來設置變量的默認值,當活動命令被調用時,默認賦值仍然會執行,並輸出顯示結果。
=句法
下面的語句和:=句法非常類似,但是沒有冒號。
username=””
echo “${username=$LOGNAME}”
和前面一樣,變量username已經被定義,但是它的值為空。在這個句法中,命令將會輸出“echo”之后語句的執行結果。因為變量username雖然為空值,但已經被定義了,所以除了一個回車不會再有其他輸出。只有當username變量完全沒有定義時,才會將其設置為變量LOGNAME的值。
當腳本或者函數需要依賴某些定義變量時,就要使用這種語法。它主要應用於登陸。如果一個特定環境變量還沒有被定義,就可以給它賦予腳本所需要的值。
:-句法
在這個命令中,因為變量username雖然已被定義但是為空值,echo語句將使用LOGNAME變量的值。
username=””
echo “${username:-$LOGNAME}”
這里username變量的值保持不變。這個命令和使用=句語法的不同之處是,在此命令被執行前,僅僅在代碼中的“${}”句法中做替換。也就是說,echo命令將輸出LOGNAME變量的值,但是這個值不會被賦給username變量。
-句法
當刪除上述的:-語句中的冒號,即變成-的時候,因為username變量已被定義,輸出將為空。如果未定義,就會使用LOGNAME變量的值。還有一點也與:-句法相同,即username變量的值沒有改變。
username=””
echo “${username-$LOGNAME}”
當腳本評價或檢查系統環境的時,:-句法和-句法都可以使用。這兩種檢查基本上是相反的,它們用默認值替換變量,或者甚至於不依賴username變量是否已經被定義。如果腳本中急需要一組被定義的變量,也需要一些不該被定義的變量,那么在腳本執行任務之前組合這兩種句法,肯定可以實現正確的設置。
:?句法
使用:?句法時,如果username變量已被定義為非空值,在echo命令中就會使用username變量的值。如果username變量已被定義但卻沒有一個真正的值(也就是說非空)或者完全未被定義,那么在echo命令中就會使用LOGNAME的值,並且腳本退出執行。
username=””
echo “${username:?$LOGNAME}”
如果把問號字符的參數改為某種錯誤字符,那這個語句就會在代碼調試和查找未定義變量時變得很有用。這段代碼不僅僅輸出字符串,而且會顯示代碼在腳本中所在行的位置。
?句法
從:?句法中去掉冒號使用username變量不必一定為非空值。如果username只被設置為一個空值,那么將使用這個空值。相反的,如果username變量沒有被定義,則同前所述的:?句法,執行LOGNAME替換,腳本退出運行,並顯示退出時所在代碼行在腳本中的位置。
username=””
echo “${username?$LOGNAME}”
在腳本調試過程中,需要檢查變量是否已被定義或者是非空的是否,:?和?句法是非常有用的。這個代碼最大的優點是腳本會從出錯行退出,而且會顯示出錯誤行行號。在要顯示的文本中加上類似於“is undefined”或者“has a null value”信息,可以更清楚的說明腳本中的問題。
:+句法
和前面的例子相比,這個句法有相反的作用。這這是因為,只有當變量已被定義而不是未定義的時候,“${}”表達式才執行替換。
username=””
echo “${username:+$LOGNAME}”
如果這里的username變量已被定義而且非空,因此使用LOGNAME的值。如果username變量未定義,或者已定義但為空,則將使用空值。在任何情況下,username變量的值都不會改變。
+句法
如果 前例:+中的冒號,一旦變量username被定義,“${}”表達式都將使用LOGNAME的值;進行這個替換時,username變量不需要有一個實際的值(即非空值)。如
username=””
echo “${username+$LOGNAME}”
“:+”、“+”句法的用法很多是喝“:-”、“-”句法的用法相同的。最主要的區別是“:+”、“+”示例檢查的是一個已定義的變量,而不是未定義的變量。這類類似於家法、減法——一枚硬幣的兩面。
================== End