# 4.1 變量替換
變量名是其所指向值的一個占位符(placeholder)。引用變量值的過程我們稱之為變量替換(variable substitution)。
### $
接下來我們仔細區分一下**變量名**與**變量值**。如果變量名是 `variable1`, 那么 `$variable1` 就是對變量值的引用。[^1]
```
bash$ variable1=23
bash$ echo variable1
variable1
bash$ echo $variable1
23
```
變量僅僅在聲明時、賦值時、被刪除時(`unset`)、被導出時(`export`),算術運算中使用雙括號結構((...))時或在代表信號時(signal,查看樣例 32-5)才不需要有 $ 前綴。賦值可以是使用 =(比如 `var1=27`),可以是在 `read` 語句中,也可以是在循環的頭部(`for var2 in 1 2 3`)。
在雙引號`""`字符串中可以使用變量替換。我們稱之為部分引用,有時候也稱弱引用。而使用單引號`''`引用時,變量只會作為字符串顯示,變量替換不會發生。我們稱之為全引用,有時也稱強引用。更多細節將在第五章講解。
實際上, `$variable` 這種寫法是 `${variable}` 的簡化形式。在某些特殊情況下,使用 `$variable` 寫法會造成語法錯誤,使用完整形式會更好(查看章節 10.2)。
樣例 4-1. 變量賦值與替換
```bash
#!/bin/bash
# ex9.sh
# 變量賦值與替換
a=375
hello=$a
# ^ ^
#----------------------------------------------------
# 初始化變量時,賦值號 = 的兩側絕不允許有空格出現。
# 如果有空格會發生什么?
# "VARIABLE =value"
# ^
#% 腳本將會嘗試運行帶參數 "=value" 的 "VARIABLE " 命令。
# "VARIABLE= value"
# ^
#% 腳本將會嘗試運行 "value" 命令,
#+ 同時設置環境變量 "VARIABLE" 為 ""。
#----------------------------------------------------
echo hello # hello
# 沒有引用變量,"hello" 只是一個字符串...
echo $hello # 375
# ^ 這是變量引用。
echo ${hello} # 375
# 與上面的類似,變量引用。
# 字符串內引用變量
echo "$hello" # 375
echo "${hello}" # 375
echo
hello="A B C D"
echo $hello # A B C D
echo "$hello" # A B C D
# 正如我們所見,echo $hello 與 echo "$hello" 的結果不同。
# ====================================
# 字符串內引用變量將會保留變量的空白符。
# ====================================
echo
echo '$hello' # $hello
# ^ ^
# 單引號會禁用掉(轉義)變量引用,這導致 "$" 將以普通字符形式被解析。
# 注意單雙引號字符串引用效果的不同。
hello= # 將其設置為空值
echo "\$hello (null value) = $hello" # $hello (null value) =
# 注意
# 將一個變量設置為空與刪除(unset)它不同,盡管它們的表現形式相同。
# -----------------------------------------------
# 使用空白符分隔,可以在一行內對多個變量進行賦值。
# 但是這會降低程序的可讀性,并且可能會導致部分程序不兼容的問題。
var1=21 var2=22 var3=$V3
echo
echo "var1=$var1 var2=$var2 var3=$var3"
# 在一些老版本的 shell 中這樣寫可能會有問題。
# -----------------------------------------------
echo; echo
numbers="one two three"
# ^ ^
other_numbers="1 2 3"
# ^ ^
# 如果變量中有空白符號,那么必須用引號進行引用。
# other_numbers=1 2 3 # 出錯
echo "numbers = $numbers"
echo "other_numbers = $other_numbers" # other_numbers = 1 2 3
# 也可以轉義空白符。
mixed_bag=2\ ---\ Whatever
# ^ ^ 使用 \ 轉義空格
echo "$mixed_bag" # 2 --- Whatever
echo; echo
echo "uninitialized_variable = $uninitialized_variable"
# 未初始化的變量是空值(null表示不含有任何值)。
uninitialized_variable= # 只聲明而不初始化,等同于設為空值。
echo "uninitialized_variable = $uninitialized_variable" # 仍舊為空
uninitialized_variable=23 # 設置變量
unset uninitialized_variable # 刪除變量
echo "uninitialized_variable = $uninitialized_variable"
# uninitialized_variable =
# 變量值為空
echo
exit 0
```
>  一個未被賦值或未初始化的變量擁有空值(null value)。*注意:null值不等同于0*。
>
```bash
if [ -z "$unassigned" ]
then
echo "\$unassigned is NULL."
fi # $unassigned is NULL.
```
> 在賦值前使用變量可能會導致錯誤。但在算術運算中使用未賦值變量是可行的。
>
```bash
echo "$uninitialized" # 空行
let "uninitialized += 5" # 加5
echo "$uninitialized" # 5
# 結論:
# 一個未初始化的變量不含值(null),但在算術運算中會被作為0處理。
```
>
> 也可參考樣例 15-23。
[^1]: 實際上,變量名是被稱作左值(lvalue),意思是出現在賦值表達式的左側的值,比如 `VARIABLE=23`。變量值被稱作右值(rvalue),意思是出現在賦值表達式右側的值,比如 `VAR2=$VARIABLE`。<br />事實上,變量名只是一個引用,一枚指針,指向實際存儲數據內存地址的指針。
- 第一部分 初見shell
- 1. 為什么使用shell編程
- 2. 和Sha-Bang(#!)一起出發
- 2.1 調用一個腳本
- 2.2 牛刀小試
- 第二部分 shell基礎
- 3. 特殊字符
- 4. 變量與參數
- 4.1 變量替換
- 4.2 變量賦值
- 4.3 Bash弱類型變量
- 4.4 特殊變量類型
- 5. 引用
- 5.1 引用變量
- 5.2 轉義
- 6. 退出與退出狀態
- 7. 測試
- 7.1 測試結構
- 7.2 文件測試操作
- 7.3 其他比較操作
- 7.4 嵌套 if/then 條件測試
- 7.5 牛刀小試
- 8. 運算符相關話題
- 8.1 運算符
- 8.2 數字常量
- 8.3 雙圓括號結構
- 8.4 運算符優先級
- 第三部分 shell進階
- 10. 變量處理
- 10.1 字符串處理
- 10.1.1 使用 awk 處理字符串
- 10.1.2 參考資料
- 10.2 參數替換
- 11. 循環與分支
- 11.1 循環
- 11.2 嵌套循環
- 11.3 循環控制
- 11.4 測試與分支
- 12. 命令替換
- 13. 算術擴展
- 14. 休息時間
- 第五部分 進階話題
- 19. 嵌入文檔
- 20. I/O 重定向
- 20.1 使用 exec
- 20.2 重定向代碼塊
- 20.3 應用程序
- 22. 限制模式的Shell
- 23. 進程替換
- 26. 列表結構
- 25. 別名