跳轉到內容

Bash Shell 指令碼/變數

來自華夏公益教科書,開放的書籍,為開放的世界

在 Bash 指令碼中,有幾種不同型別的引數可以儲存。一種主要型別的引數是變數:命名的引數。如果您熟悉任何其他指令式程式設計語言(例如 C、BASIC、Fortran 或 Pascal),那麼您已經熟悉變數。以下簡單指令碼使用變數location儲存值world,並輸出“Hello, world!”訊息

location=world               # store "world" in the variable "location"
echo "Hello, ${location}!"   # print "Hello, world!"

如您所見,第二行中的字串${location}在執行該命令之前被替換為world。這種替換被稱為變數擴充套件

注意

此處空格的缺失很重要!命令location = worldlocation= worldlocation =world將無法正常工作。例如,對於location = world,它將嘗試使用引數=world執行命令location

變數擴充套件比您想象的更靈活。例如,它甚至可以儲存要執行的命令的名稱

cmd_to_run=echo                   # store "echo" in the variable "cmd_to_run"
"${cmd_to_run}" 'Hello, world!'   # print "Hello, world!"

在以上兩個示例中,我們都使用了${variable_name}表示法來執行變數擴充套件。更簡短的表示法$variable_name(不帶花括號)在這些情況下將具有相同的效果。有時需要花括號(例如,${foo}bar不能寫成$foobar,因為後者將被解釋為${foobar}),但通常可以省略它們,並且現實世界的指令碼通常省略它們。

當然,不必說,以上並不是非常現實的例子;它們只演示了如何使用變數,而不是為什麼何時使用它們。如果您熟悉其他指令式程式設計語言,那麼您可能已經清楚地知道為什麼以及何時使用變數;如果不是,那麼當您閱讀本書並看到更現實地使用它們的示例時,這一點應該會變得清晰。

您可能已經注意到,對於包含變數擴充套件的字串,我們使用了雙引號",而不是單引號'。這是因為單引號會阻止變數擴充套件;類似echo '${location}'的命令將列印實際字串${location},而不是列印名為location的變數的值。

通常建議將變數擴充套件括在雙引號中,因為否則變數擴充套件的結果將經過檔名擴充套件,以及單詞分割(透過空格來分隔構成命令的單詞)。例如,此指令碼

foo='a  b*'    # store "a  b*" in the variable "foo"
echo $foo

可能列印類似a ba.txt bd.sh的內容,這可能不是我們想要的。現實世界的指令碼通常不包含雙引號,除非它們是明確必要的,但這種做法有時會導致令人困惑的錯誤。

提示

通常建議將變數擴充套件括在雙引號中;例如,使用"$var"而不是$var

許多變數具有特殊的意義。例如,變數PATH決定了 Bash 在嘗試執行外部程式時應該搜尋的目錄列表;如果它設定為/usr/bin:/bin,那麼命令cp src.txt dst.txt將嘗試執行/usr/bin/cp/bin/cp。變數HOME預先初始化為當前使用者的 home 目錄,它決定了波浪號擴充套件的行為。例如,如果一個指令碼設定了HOME=/foo,那麼echo ~/bar將列印/foo/bar。(但是,這並不會真正改變使用者的 home 目錄。)

華夏公益教科書