變量是任何一種編程語言都必不可少的組成部分,變量用來存放各種數據。腳本語言在定義變量時通常不需要指明類型,直接賦值就可以,Shell 變量也遵循這個規則。
在 Bash shell 中,每一個變量的值都是字符串,無論你給變量賦值時有沒有使用引號,值都會以字符串的形式存儲。
這意味着,Bash shell 在默認情況下不會區分變量類型,即使你將整數和小數賦值給變量,它們也會被視為字符串,這一點和大部分的編程語言不同。
例如在 C/C++ 中,變量分為整數、小數、字符串、布爾等多種類型。
當然,如果有必要,你也可以使用 declare 關鍵字顯式定義變量的類型,但在一般情況下沒有這個需求,Shell 開發者在編寫代碼時自行注意值的類型即可。
定義變量
Shell 支持以下三種定義變量的方式:
variable=value
variable='value'
variable="value"
variable 是變量名,value 是賦給變量的值。如果 value 不包含任何空白符(例如空格、Tab縮進等),那么可以不使用引號;如果 value 包含了空白符,那么就必須使用引號包圍起來。使用單引號和使用雙引號也是有區別的,稍后我們會詳細說明。
注意,賦值號的周圍不能有空格,這可能和你熟悉的大部分編程語言都不一樣。
Shell 變量的命名規范和大部分編程語言都一樣:
- 變量名由數字、字母、下划線組成;
- 必須以字母或者下划線開頭;
- 不能使用 Shell 里的關鍵字(通過 help 命令可以查看保留關鍵字)。
變量定義舉例:
- url=http://cnblogs.com/chengkanghua
- echo $url
- name='C語言'
- echo $name
- author="ckh"
- echo $author
使用變量
使用一個定義過的變量,只要在變量名前面加美元符號$
即可,如:
- author="ckh"
- echo $author
- echo ${author}
變量名外面的花括號{ }
是可選的,加不加都行,加花括號是為了幫助解釋器識別變量的邊界,比如下面這種情況:
- skill="Java"
- echo "I am good at ${skill}Script"
如果不給 skill 變量加花括號,寫成echo "I am good at $skillScript"
,解釋器就會把 $skillScript 當成一個變量(其值為空),代碼執行結果就不是我們期望的樣子了。
推薦給所有變量加上花括號{ }
,這是個良好的編程習慣。
修改變量的值
已定義的變量,可以被重新賦值,如:
- url="http://cnblogs.com/chengkanghua"
- echo ${url}
- url="http://cnblogs.com/chengkanghua/shell/"
- echo ${url}
第二次對變量賦值時不能在變量名前加$
,只有在使用變量時才能加$
。
單引號和雙引號的區別
前面我們還留下一個疑問,定義變量時,變量的值可以由單引號' '包圍,也可以由雙引號" "包圍,它們到底有什么區別呢?不妨以下面的代碼為例來說明:
- #!/bin/bash
- url="http://cnblogs.com"
- website1='C語言:${url}'
- website2="C語言:${url}"
- echo $website1
- echo $website2
運行結果:
C語言:${url}
C語言:http://cnblogs.com
以單引號' '
包圍變量的值時,單引號里面是什么就輸出什么,即使內容中有變量和命令(命令需要反引起來)也會把它們原樣輸出。這種方式比較適合定義顯示純字符串的情況,即不希望解析變量、命令等的場景。
以雙引號" "包圍變量的值時,輸出時會先解析里面的變量和命令,而不是把雙引號中的變量名和命令原樣輸出。這種方式比較適合字符串中附帶有變量和命令並且想將其解析后再輸出的變量定義。
嚴長生的建議:如果變量的內容是數字,那么可以不加引號;如果真的需要原樣輸出就加單引號;其他沒有特別要求的字符串等最好都加上雙引號,定義變量時加雙引號是最常見的使用場景。
將命令的結果賦值給變量
Shell 也支持將命令的執行結果賦值給變量,常見的有以下兩種方式:
variable=`command`
variable=$(command)
第一種方式把命令用反引號包圍起來,反引號和單引號非常相似,容易產生混淆,所以不推薦使用這種方式;第二種方式把命令用$()
包圍起來,區分更加明顯,所以推薦使用這種方式。
例如,我在 code 目錄中創建了一個名為 log.txt 的文本文件,用來記錄我的日常工作。下面的代碼中,使用 cat 命令將 log.txt 的內容讀取出來,並賦值給一個變量,然后使用 echo 命令輸出。
[ckh@localhost ~]$ cd code [ckh@localhost code]$ log=$(cat log.txt) [ckh@localhost code]$ echo $log [2017-09-10 06:53:22] 牛人正在編寫Shell教程 [ckh@localhost code]$ log=`cat log.txt` [ckh@localhost code]$ echo $log [2017-09-10 06:53:22] 牛人正在編寫Shell教程 [ckh@localhost code]$
只讀變量
使用 readonly 命令可以將變量定義為只讀變量,只讀變量的值不能被改變。
下面的例子嘗試更改只讀變量,結果報錯:
- #!/bin/bash
- myUrl="http://see.xidian.edu.cn/cpp/shell/"
- readonly myUrl
- myUrl="http://see.xidian.edu.cn/cpp/danpianji/"
運行腳本,結果如下:
/bin/sh: NAME: This variable is read only.
刪除變量
使用 unset 命令可以刪除變量。語法:
- unset variable_name
變量被刪除后不能再次使用;unset 命令不能刪除只讀變量。
舉個例子:
- #!/bin/sh
- myUrl="http://see.xidian.edu.cn/cpp/u/xitong/"
- unset myUrl
- echo $myUrl
上面的腳本沒有任何輸出。
變量類型
運行shell時,會同時存在三種變量:
1) 局部變量
局部變量在腳本或命令中定義,僅在當前shell實例中有效,其他shell啟動的程序不能訪問局部變量。
2) 環境變量
所有的程序,包括shell啟動的程序,都能訪問環境變量,有些程序需要環境變量來保證其正常運行。必要的時候shell腳本也可以定義環境變量。
3) shell變量
shell變量是由shell程序設置的特殊變量。shell變量中有一部分是環境變量,有一部分是局部變量,這些變量保證了shell的正常運行