變量替換和變量默認值設置是緊密相關的,至少從概念出發是如此。linux
參數擴張是將相似於變量的參數用它的值來替換。例如以「echo $VAR」的形式調用一個簡單的變量。此外還有更多的特性能夠訪問。這個句法還包含一些沒有擴展的特性,雖然這些特性自身頗有意義。首先,這類特性執行默認變量賦值。使用這些特性時,整個表達式須要用花括號括起來。程序員
: ${VAR:=」some default」}shell
這些代碼開始的冒號是一個正確執行非活動任務的shell命令。在這個句法中,它僅僅擴展了行中緊隨其後的全部參數。本例中,只要是要在花括號內擴展參數值。bash
本行ongoing冒號中的參數是最有趣的部分;它是用花括號起來的一些邏輯的參數擴展。:=句法表示VAR變量將會和「some defalut」字符串進行比較。函數
在這個表達式中,若是變量VAR尚未被設置,那麼「:=」以後表達式的值將被賦給它,這個值多是一個數字,一個字符串,或者是另一個變量。編碼
系統中的腳步可能須要將多個變量設置成默認值。程序員能夠在一行中給多個變量設置默認值,而不是編碼一組變量替換,這樣也使得代碼更加緊湊、易讀。下面的例子包含了程序員須要執行的各類替換操做。第一個默認值是一個顯示的串,第二個是一個顯示的整數,第三個是一個已定義的變量。調試
這幾個變量替換類型和前例中的:=句法相似。由於不一樣替換類型的句法都是相同的,不過它們的意義卻略有不一樣,可能很容易混淆。在大多數狀況下,代碼中執行替換句法的地方,這些替換僅僅用某個值替換了變量,可是並無設置變量,也就是說變量並無被真正賦值。下面句法類型的定義在全部的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}」
「:+」、「+」句法的用法不少是喝「:-」、「-」句法的用法相同的。最主要的區別是「:+」、「+」示例檢查的是一個已定義的變量,而不是未定義的變量。這類相似於家法、減法——一枚硬幣的兩面。