變量
簡介
變量就是程序設計語言中的一個可以變化的量,當然,可以變化的是變量的值。變量幾乎所有的程序設計語言中都有定義,並且其涵義也大同小異。從本質上講,變量就是在程序中保存用戶數據的一塊內存空間,而變量名就是這塊內存空間的地址。
在程序的執行過程中,保存數據的內存空間的內容可能會不斷地發生變化,但是,代表內存地址的變量名卻保持不變。
命名
在Shell中,變量名可以由字母、數字或者下划線組成,並且只能以字母或者下划線開頭。對於變量名的長度,Shell並沒有做出明確的規定。因此,用戶可以使用任意長度的字符串來作為變量名。但是,為了提高程序的可讀性,建議用戶使用相對較短的字符串作為變量名。
在一個設計良好的程序中,變量的命名有着非常大的學問。通常情況下,用戶應該盡可能選擇有明確意義的英文單詞作為變量名,盡量避免使用拼音或者毫無意義的字符串作為變量名。這樣的話,用戶通過變量名就可以了解該變量的作用。
例如,下面的變量名都是非常好的選擇:
PATH=/sbin
UID=100
JAVA_HOME="/usr/lib/jvm/jre-1.6.0-openjdk.x86_64/bin/../.."
SSHD=/usr/sbin/sshd
1
2
3
4
變量的類型
Shell是一種動態類型語言和弱類型語言,即在Shell中,變量的數據類型毋需顯示地聲明,變量的數據類型會根據不同的操作有所變化。准確地講,Shell中的變量是不分數據類型的,統一地按照字符串存儲。 但是根據變量的上下文環境,允許程序執行一些不同的操作,例如字符串的比較和整數的加減等等。
【例1】演示Shell變量的數據類型
#!/bin/bash
x=123 #定義變量x,並且賦值為123
let "x += 1" #變量x加1
echo "x = $x" #輸出變量x的值 124
echo #顯示空行
y=${x/1/abc} #替換x中的1為abc,並且將值賦給變量y abc24
echo "y = $y" #輸出變量y的值 abc24
declare -i y #聲明變量y
echo "y = $y" #輸出變量y的值
let "y += 1" #變量y的值加1 #abc24不是整形,便將y變為0,0自增為1
echo "y = $y" #輸出變量y的值 1
echo #顯示空行
z=abc22 #將字符串賦給變量z
echo "z = $z" #輸出變量z的值
m=${z/abc/11} #替換變量z中的abc為數字11,並且將值賦給變量m
echo "m = $m" #輸出變量m的值
let "m += 1" #變量m加1 #弱類型,自動變為int型
echo "m = $m" #輸出變量m的值
echo
n="" #將空串賦給變量n
echo "n = $n" #輸出變量n的值
let "n += 1" #變量n加1
echo "n = $n"
echo
echo "p = $p" #輸出空變量p的值 #自動賦值為空
let "p += 1" # 變量p加1
echo "p = $p"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
上述代碼運行結果
[root@localhost ~]# ./test.sh
x = 124
y = abc24
y = abc24
y = 1
z = abc22
m = 1122
m = 1123
n =
n = 1
p =
p = 1
1
2
3
4
5
6
7
8
9
10
11
12
在Shell中,通常情況下用戶可以直接使用變量,而毋需先進行定義,當用戶第一次使用某個變量名時,實際上就同時定義了這個變量,在變量的作用域內,用戶都可以使用該變量。
【例2】演示通過直接使用變量來定義變量
#!/bin/bash
a=1 #定義變量a #類似於 int n=3 這種操作
b="hello" #定義變量b
c="hello world" #定義變量c
1
2
3
4
通過declare命令聲明變量
declare attribute variable(聲明變量屬性)
-p:顯示所有變量的值。
-i:將變量定義為整數。在之后就可以直接對表達式求值,結果只能是整數。如果求值失敗或者不是整數,就設置為0。
declare -i t,把t設置為整型
-r:將變量聲明為只讀變量。只讀變量不允許修改,也不允許刪除。readonly,
-a:變量聲明為數組變量。但這沒有必要。所有變量都不必顯式定義就可以用作數組。事實上,在某種意義上,似乎所有變量
都是數組,而且賦值給沒有下標的變量與賦值給下標為0的數組元素相同. array,矩陣,變長數組
-f:顯示所有自定義函數,包括名稱和函數體。function
-x:將變量設置成環境變量,這樣在隨后的腳本和程序中可以使用。
1
2
3
4
5
6
7
8
【例3】演示使用不同的方法了聲明變量,導致變量在不同的環境下表現出不同的行為
#!/bin/bash
x=6/3 #定義變量x,並將一個算術式賦給它
echo "$x"
declare -i x #定義變量x為整數
echo "$x" #仍為之前的x
x=6/3 #將算術式賦給變量x,自動轉變為2
echo "$x" #
x=hello #將字符串賦給變量x
echo "$x" #給整型變量賦hello,不是整數,只能給x賦值為0
x=3.14 #將浮點數賦給變量x
echo "$x"
declare +i x #取消變量x的整數屬性
x=6/3 #重新將算術式賦給變量x
echo "$x" #6/3
x=$[6/3] #求表達式的值
echo "$x" #2
x=$((6/3)) #求表達式的值
echo "$x" #2
declare -r x #聲明只讀變量x
echo "$x" #2
x=5 #嘗試為只讀變量賦值
echo "$x” #2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
運行以上程序
[root@localhost ~]# ./test.sh
6/3
6/3
2
0
./test.sh: line 10: 3.14: syntax error: invalid arithmetic operator (error token is ".14")
0
6/3
2
2
2
./test.sh: line 21: x: readonly variable
2
1
2
3
4
5
6
7
8
9
10
11
12
13
引用
Shell語言中一共有3種引號,分別為
單引號(’ ')單引號括起來的字符都作為普通字符出現
雙引號(" ")雙引號括起來的字符,除“$”、“\”、“ ’ ”和“ " ”這幾個字符仍是特殊字符並保留其特殊功能外,其余字符仍作為普通字符對待,
反引號(` `)。反引號括起來的字串被Shell解釋為命令,在執行時,Shell首先執行該命令,並以它的標准輸出結果取代整個反引號(包括兩個反引號)部分
【例4】演示反引號使用方法
#!/bin/bash
#輸出當前目錄
echo "current directory is `pwd`"
1
2
3
運行以上程序
[root@localhost ~]# ./test.sh
current directory is /root
1
2
【例5】演示單雙引號使用方法
#!/bin/bash
a= demo
b='b- $a'
c="b- $a"
echo $a
echo $b
echo $c
運行結果如下:
demo
b- $a #單引號,所見即所得
b- demo
1
2
3
4
5
6
7
8
9
10
11
三種引號的理解:
1、單引號(弱引用)
所見即所得
例如:var=123
var2=’${var}123’
echo var2 var2結果為${var}123
2、雙引號(強引用)
輸出引號中的內容,若存在命令、變量等,會先執行命令解析出結果再輸出
例如:var=123
var2="${var}123"
echo var2 var2結果為123123
3、反引號(鍵盤tab鍵上面一個鍵)
命令替換
例如:root用戶登錄系統
var=`whoami`
echo $var var結果為執行whoami命令的結果 顯示root
備注:反引號和$()作用相同
對三種引號的建議:
1、簡單變量,簡單賦值可以不用""
2、腳本中聲明變量最好用""
3、原樣子輸出用’’
4、執行命令賦值最好用$()或者``
變量的作用域
Shell中的變量也分為全局變量和局部變量2種
1.全局變量
全局變量可以在腳本中定義,也可以在某個函數中定義。在腳本中定義的變量都是全局變量,其作用域為從被定義的地方開始,一直到Shell腳本結束或者被顯式地刪除
【例6】 演示全局變量的使用方法
#!/bin/bash
func() #定義函數
{
echo "$v1" #輸出變量x的值
v1=200 #修改變量x的值
}
v1=100 #在腳本中定義變量x
func #調用函數
echo "$v1" #輸出變量x的值
1
2
3
4
5
6
7
8
9
運行以上程序
[root@localhost ~]# ./test.sh
100
200
1
2
3
【例7】演示在函數內部定義全局變量的方法
#!/bin/bash
func() #定義函數
{
v2=200 #在函數內部定義變量
}
func #調用函數
echo "$v2" #輸出變量的值
1
2
3
4
5
6
7
8
運行以上程序
[root@localhost ~]# ./test.sh
200
1
2
2、局部變量
與全局變量相比,局部變量的使用范圍較小,通常僅限於某個程序段訪問,例如函數內部。在Shell語言中,可以在函數內部通過local關鍵字定義局部變量,另外,函數的參數也是局部變量。
【例8】演示使用local關鍵字定義局部變量
#!/bin/bash
func() #定義函數
{
local v2=200 #使用local關鍵字定義局部變量,僅在函數體內部起作用,函數調用完畢,就完了
}
func #調用函數
echo "$v2" #輸出變量的值
1
2
3
4
5
6
7
運行以上程序
[root@localhost ~]# ./test.sh
//NULL
1
2
【例9】演示全局變量和局部變量的區別
#!/bin/bash
func() #定義函數
{
echo "global variable v1 is $v1" #輸出全局變量v1的值
local v1=2 #定義局部變量v1
echo "local variable v1 is $v1" #輸出局部變量v1的值
}
v1=1 #定義全局變量v1
func #調用函數
echo "global variable v1 is $v1" #輸出全局變量v1的值
1
2
3
4
5
6
7
8
9
10
運行以上程序
[root@localhost ~]# ./test.sh
global variable v1 is 1
local variable v1 is 2
global variable v1 is 1
1
2
3
4
【例10】演示全局變量和局部變量的區別(二)
#!/bin/bash
function test() {
local a
a="hello world"
echo $a
}
test
echo $a
1
2
3
4
5
6
7
8
運行以上程序
[root@localhost ~]# ./test.sh
hello world
//全局變量a無值
1
2
3
對比如下:
#!/bin/bash
function test() {
a="hello world"
echo $a
}
test
echo $a
1
2
3
4
5
6
7
運行以上程序
[root@localhost ~]# ./test.sh
hello world
hello world
1
2
3
總結:
1、全局變量總結
環境變量即為全局變量,可以在定義它們的shell及其派生出來的任意子進程的shell中使用。局部變量只能在定義它們的函數/腳本中使用。還有一些變量是用戶創建的,其他的則是專用的shell變量。環境變量可用於定義shell的運行環境,環境變量可以在配置文件中定義與修改,也可以在命令行中設置,但是命令行中的修改操作在終端重啟時就會丟失,因此最好在配置文件中修改(用戶家目錄的“.bash_profile“文件或者全局配置“/etc/profile”、“/etc/bashrc”文件或者“/etc/profile.d”文件中定義。)將環境變量放在profile文件中,每次用戶登錄時這些變量值將被初始化。比如HOME、USER、SHELL、UID等再用戶登錄之前就已經被/bin/login程序設置好了。
常見的系統環境變量如下:
TMOUT: 設置自動退出的誤操作等待時間
HOSTTYPE: 系統文件系統類型
HISTSIZE: 歷史命令記錄條數
HOME: 用戶登錄時進入的目錄,家目錄
UID: 當前用戶的id
SHELL: 當前shell解釋器
PWD: 當前所在路徑(每改變一次目錄,該值就會改變)
PATH: 可執行文件默認路徑
可以用echo來顯示查看全局變量(eg:echo $HOME)。env(或printenv)、set也可以用來查看系統的環境變量,但不是單獨查看。而用unset臨時取消環境變量(eg:unset USER),要永久生效還是要寫到配置文件中
自定義環境變量(采用export):
①export 變量名=value
②變量名=value;export 變量名
③declare -x 變量名=value
這里依舊是臨時生效,在shell終端關閉后就消失了,寫到配置文件中則永久生效(注意:寫到配置文件中后需要運行一遍配置文件的腳本才可生效,否則等重啟時生效)
2.局部變量總結
局部變量即為本地變量,本地變量在用戶當前的shell生存期的腳本中使用。在一個函數中將某個變量聲明為local,則該變量就是一個局部變量,只在本函數中有效。
3.關於局部變量的一些其他問題:
①用反引號將命令的結果作為變量名是常用的方法,eg:cmd=`date +%F`
②用$符號將命令的結果作為變量名也比較常用,eg:cmd=$(date +%F)
③變量在大括號上的使用:在以時間、主機名等為包名一部分來打包的時候常用
【例11】用時間作為文件名的一部分打包:
#!/bin/bash
cmd=$(date +%F) #由於`date +%F`的反引號不容易辨認,就不太使用`date +%F`
tar -zcf code_$(date +%F)_young1.tar.gz /etc #沒有問題
tar -zcf code_`date +%F`_young2.tar.gz /etc #沒有問題
tar -zcf code_young3_$cmd.tar.gz /etc #沒有問題
tar -zcf code_$cmd_young4.tar.gz /etc #會有歧義,因為系統會不清楚是應該解析$cmd還是cmd_young
tar -zcf code_${cmd}_young5.tar.gz /etc #不會有歧義
1
2
3
4
5
6
7
運行結果如下:
[root@localhost ~]# ./test.sh
tar: Removing leading `/' from member names
tar: Removing leading `/' from member names
tar: Removing leading `/' from member names
tar: Removing leading `/' from member names
tar: Removing leading `/' from member names
[root@localhost ~]# ls -l code*
-rw-r--r--. 1 root root 9166435 Jun 5 03:39 code_2019-06-05_young1.tar.gz
-rw-r--r--. 1 root root 9166435 Jun 5 03:39 code_2019-06-05_young2.tar.gz
-rw-r--r--. 1 root root 9166435 Jun 5 03:39 code_2019-06-05_young5.tar.gz
-rw-r--r--. 1 root root 9166435 Jun 5 03:39 code_.tar.gz //中間變量不存在,用null替換了
-rw-r--r--. 1 root root 9166435 Jun 5 03:39 code_young3_2019-06-05.tar.gz
1
2
3
4
5
6
7
8
9
10
11
12
【例12】用主機名與時間打包:
#!/bin/bash
cmd=$(date +%F)
host=$(hostname)
tar -zcf code_${cmd}_${host}.tar.gz /etc
1
2
3
4
運行結果如下:
[root@localhost ~]# ls -l code*
-rw-r--r--. 1 root root 9166435 Jun 5 04:10 code_2019-06-05_localhost.localdomain.tar.gz
因此,養成將字符串括起來使用的習慣防止不易發現的錯誤
1
2
3
關於$?的補充:
[root@localhost ~]# vim test.cpp
#include<iostream>
using namespace std;
int main()
{
return 256; //超過上限,返回值范圍為0-255,所以后面echo $?為0
}
[root@localhost ~]# rm -rf test
[root@localhost ~]# make test
g++ test.cpp -o test
[root@localhost ~]# ./test
[root@localhost ~]# echo $?
0
[root@localhost ~]# vim test.cpp
#include<iostream>
using namespace std;
int main()
{
return 255; //此處255在合法范圍內,第一個vim中,該值設為256,產生上溢,為0,即返回給父進程的值只能是0-255.
}
[root@localhost ~]# make test
g++ test.cpp -o test
[root@localhost ~]# ./test
[root@localhost ~]# echo $?
255
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
關於$?在腳本中的應用:
常用來判斷上一步是否成功(壓縮失敗打印ERROR壓縮成功打印OK):
[root@foundation0 ~]# cat test.sh
#!/bin/bash
tar profile.tar.gz /etc/profile >& /dev/null
[ $? -eq 0 ] && echo "tar profile OK" || echo "tar profile ERROR"
tar -zcf profile.d.tar.gz /etc/profile.d >& /dev/null
[ $? -eq 0 ] && echo " tar profile.d OK" || echo "tar profile.d ERROR"
[root@localhost ~]# ./test.sh
tar profile ERROR
tar profile.d OK
1
2
3
4
5
6
7
8
9
10
系統變量
Shell語言的系統變量主要在對參數判斷和命令返回值判斷時使用,包括腳本和函數的參數以及腳本和函數的返回值
變量 說明
$n 表示傳遞給腳本的第n個參數,例如$1表示第1個參數,$2表示第2個參數…
$# 命令行參數的個數
$0 當前腳本的名稱
$? 前一個命令或者函數的返回狀態碼
$* 以“參數1 參數2 參數3…”的形式返回所有參數的值
$@ 以“參數1” “參數2” “參數3”…的形式返回所有參數的值
$_ 保存之前執行的命令的最后一個參數
$$ 返回本程序的進程ID(PID)
【例13】演示常用系統變量的使用方法
#!/bin/bash
echo "the number of parameters is $#" #輸出腳本的參數個數
echo "the return code of last command is $?" #輸出上一個命令的退出狀態碼
echo "the script name is $0" #輸出當前腳本名稱
echo "the parameters are $*" #輸出所有的參數
echo "\$1=$1;\$2=$2;\$11=${11}" #輸出其中的幾個參數
1
2
3
4
5
6
運行以上程序
[root@localhost ~]# ./test.sh a b c d e f g h i j k l m n
the number of parameters is 14
the return code of last command is 0
the script name is ./test.sh
the parameters are a b c d e f g h i j k l m n
$1=a;$2=b;$11=k
1
2
3
4
5
6
環境變量
Shell的環境變量是所有的Shell程序都可以使用的變量。Shell程序在運行時,都會接收一組變量,這組變量就是環境變量。環境變量會影響到所有的腳本的執行結果。
除了上表列出的環境變量之外,用戶還可以使用set命令列出當前系統的環境變量。
【例14】通過環境變量來獲取與當前Shell有關的一些環境變量的值
#!/bin/bash
echo "commands path is $PATH" #輸出命令搜索路徑
echo "current login name is $LOGNAME" #輸出當前的登錄名
echo "current user's home is $HOME" #輸出當前用戶的主目錄
echo "current shell is $SHELL" #輸出當前的Shell
echo "current path is $PWD" #輸出當前工作目錄
1
2
3
4
5
6
運行以上程序
[root@localhost ~]# ./test.sh
commands path is /usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
current login is root
current user's home is /root
current shell is /bin/bash
current path is /root
1
2
3
4
5
6
變量賦值和清空
變量賦值
在Shell中,變量的賦值使用以下語法:
variable_name=value
其中,varibale_name表示變量名,value表示變量的值。
例如,下面都是有效的賦值語句:
v1=Linux
v2='RedHat Linux'
v3="RedHat Linux $HOSTTYPE"
v4=12345
1
2
3
4
5
引用變量的值
在Shell中,通過在變量名前面加上“$”,來獲取該變量的值。相當於取該地址上的內容
【例15】演示Shell變量的
#!/bin/bash
v1=Linux
v2='RedHat Linux'
v3="RedHat Linux $HOSTTYPE"
v4=12345
echo "$v1" #輸出變量v1的值
echo "$v2" #輸出變量
echo "$v3" #輸出變量v3的值
echo "$v4" #輸出變量v4的值
1
2
3
4
5
6
7
8
9
運行以上程序
[root@localhost ~]# ./test.sh
Linux
RedHat Linux
RedHat Linux x86_64
12345
1
2
3
4
5
清除變量
當Shell變量不再需要時,使用unset語句可以將其清除。當變量被清除后,其所代表的值也會消失。基本語法如下:
unset variable_name
其中,參數varibale_name表示要清除的變量的名稱。
【例16】演示Shell變量清除方法,並且觀察在清除前后變量值的變化
#!/bin/bash
v1="Hello world" #定義變量v1
echo "$v1" #輸出v1的值
unset v1 #清除變量
echo "the value of v1 has been reset"
echo "$v1" #再次輸出變量的值
1
2
3
4
5
6
運行以上程序
[root@localhost ~]# ./test.sh
Hello world
the value of v1 has been reset
//NULL
1
2
3
4
引用和替換
變量的引用和替換是Shell對於變量功能的擴展。
引用
引用,是指將字符串用引用符號包括起來,以防止其中的特殊字符被Shell解釋為其他涵義。特殊字符是指除了字面意思之外還可以解釋為其他意思的字符。例如在Shell中,“$”符號的本身涵義是美元符號,其ASCII碼值為十進制36。除了這個涵義之外,前面已經講過,“$”符號還可以用了獲取某個變量的值,即變量替換。星號“*”也是一個特殊的字符,星號可以用來作為通配符使用。
【例17】演示星號通配符的使用方法
[root@localhost chapter3]# ll ex*
-rwxr-xr-x 1 root root 179 Jan 7 11:51 ex3-10.sh
-rwxr-xr-x 1 root root 114 Jan 7 15:49 ex3-11.sh
-rwxr-xr-x 1 root root 100 Jan 7 16:15 ex3-12.sh
1
2
3
4
符號 說明
雙引號 除美元符號、單引號、反引號和反斜線之外,其他所有的字符都將保持字面意義
單引號 所有的字符都將保持字面意義
反引號 反引號中的字符串將被解釋為Shell命令
反斜線 轉義字符,屏蔽后的字符的特殊意義
全引用(’’)
在Shell語句中,當一個字符串被單引號引用起來之后,其中所有的字符,除單引號本身之外,都將被解釋為字面意義,即字符本身的涵義。這意味着被單引號引用起來的所有的字符都將被解釋為普通的字符,這稱為全引用。
【例18】演示全引用的使用方法
#!/bin/bash
v1="value" #定義變量v1
echo 'Hello, $v1' #輸出含有變量名的字符串
1
2
3
運行以上程序
[root@localhost ~]# ./test.sh
hello,$v1
1
2
部分引用("")
對於單引號來說, 被其引用起來的所有的字符都將被解釋為字面意義。而對於雙引號來說,情況會有所不同。如果用戶使用雙引號將字符串引用起來,則其中所包含的字符除美元符號(KaTeX parse error: Expected 'EOF', got '\)' at position 15: )、反引號(`)以及反斜線(\̲)̲之外的所有的其他的字符,都將被…”、“`”和“\”仍然擁有特殊的涵義。
【例19】演示部分引用的使用方法
#!/bin/bash
v1="world" #定義變量
echo "Hello, $v1" #輸出變量的值
1
2
3
運行以上程序
[root@localhost ~]# ./test.sh
hello,world
1
2
命令替換
所謂命令替換,是指在Shell程序中,將某個Shell命令的執行結果賦給某個變量。在bash中,有2種語法可以進行命令替換,分別使用反引號和圓括號,如下:
`command`
$(command)
以上2種語法時等價的,用戶可以根據自己的習慣來選擇使用。
【例20】演示反引號的使用方法
#!/bin/bash
v1=`pwd` #變量替換
echo "current working directory is $v1" #輸出變量的值
1
2
3
運行以上程序
[root@localhost ~]# ./test.sh
current working directory is /root
1
2
轉義(\)
轉義的作用是轉換某些特殊字符的意義。轉義使用反斜線表示,當反斜線后面的一個字符具有特殊的意義時,反斜線將屏蔽該字符的特殊意義,使得Shell按照該字符的字面意義來解釋。
[root@localhost ~]# echo $SHELL
/bin/bash
[root@localhost ~]# echo \$SHELL
$SHELL
[root@localhost ~]# echo \$$SHELL
$/bin/bash
1
2
3
4
5
6
例題
1、變量賦值和替換
#!/bin/bash
# 變量賦值和替換
a=375
hello=$a
#-------------------------------------------------------------------------
# 強烈注意,在賦值的前后一定不要有空格.
# 如果有空格會發生什么?
# 如果"VARIABLE =value", 腳本將嘗試運行一個"VARIABLE"的命令,帶着一個"=value"參數.
# 如果"VARIABLE= value",
# script tries to run "value" command with
#+ 腳本將嘗試運行一個"value"的命令,帶着the environmental variable "VARIABLE" set to "".
#+ 一個被賦成""值的環境變量"VARIABLE".
#-------------------------------------------------------------------------
echo hello # 沒有變量引用,不過是個 hello 字符串
echo $hello #375
echo ${hello} # 同上
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" 將給出不同的結果.
# ^ ^
# Quoting a variable preserves whitespace.
# 引用一個變量將保留其中的空白,當然,如果是變量替換就不會保留了.
echo
echo '$hello' # $hello
# ^ ^
# 全引用的作用
#+ 將導致"$"變成一個單獨的字符.
# 注意兩種引用不同的效果
hello= # 設置為空值
echo "\$hello (null value) = $hello" #$hello (null value) =
# 注意設置一個變量為空,與 unset 它,不是一回事,雖然看起來一樣,
#unset,地址都擦除了,設置為空,保留地址
# --------------------------------------------------------------
# 可以在同一行上設置多個變量.
#+ 要以空白分隔
# 小心,這會降低可讀性,和可移植性.
var1=21 var2=22 var3=$V3
echo
echo "var1=$var1 var2=$var2 var3=$var3"
# 在老版本的"sh"上,可能會有問題.
# --------------------------------------------------------------
echo; echo
numbers="one two three"
# ^ ^
other_numbers="1 2 3"
# ^ ^
# 如果變量中有空白,那么引用就必要了.
echo "numbers = $numbers"
echo "other_numbers = $other_numbers" # other_numbers = 1 2 3
echo
echo "uninitialized_variable = $uninitialized_variable" # Uninitialized 變量為空值(根本就沒賦值).
uninitialized_variable= # 聲明,但是沒被初始化,其實和前邊設置為空值得作用是一樣的.
echo "uninitialized_variable = $uninitialized_variable" # 還是一個空值
uninitialized_variable=23 # 賦值
unset uninitialized_variable # Unset it.
echo "uninitialized_variable = $uninitialized_variable" # 還是空值
echo
exit 0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
一個空值變量,或者是根本就沒聲明的變量,在賦值之前使用它可能會引起問題. 但是還是可以用來做算術運算
2、
echo "$uninitialized" # (blank line) #空
let "uninitialized += 5" # Add 5 to it. #5
echo "$uninitialized" # 5 #5
# 結論:
# 對於一個空值變量在做算術操作的時候,就好像它的值為 0 一樣.
# This is undocumented (and probably non-portable) behavior.
# 這並沒被文檔化(可能是不可移植)的行為.
1
2
3
4
5
6
7
3、一般變量賦值
#!/bin/bash
# "裸體"變量
echo
# 變量什么時候是"裸體"的,比如前邊少了$的時候.
# 當它被賦值的時候,而不是被引用的時候.
# 賦值
a=879
echo "The value of \"a\" is $a." #879
let a=16+5 # 使用 let 賦值 #21
echo "The value of \"a\" is now $a." #21
echo
# 在 for 循環中
echo -n "Values of \"a\" in the loop are: "
for a in 7 8 9 11
do
echo -n "$a "
done
echo
echo
# 在 read 命令狀態中
echo -n "Enter \"a\" "
read a #屏幕輸入的a
echo "The value of \"a\" is now $a."
echo
exit 0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
運行以上程序
[root@localhost ~]# ./test.sh
The value of "a" is 879.
The value of "a" is now 21.
Values of "a" in the loop are: 7 8 9 11
Enter "a" 8
The value of "a" is now 8.
[root@localhost ~]#
1
2
3
4
5
6
7
8
9
10
11
4、變量賦值,一般的和比較特殊的
#!/bin/bash
a=23 # Simple case
echo $a #23
b=$a
echo $b #23
# 現在讓我們來點小變化
a=`echo Hello!` # 把 echo 命令的結果傳給變量 a
echo $a #hello!
# 注意,如果在命令擴展結構中使用一個(!)的話,在命令行中將不能工作
#+ 因為這觸發了 Bash 的"歷史機制".
# 但是,在校本里邊使用的話,歷史功能是被關閉的,所以就能夠正常運行.
a=`ls-l` # 把 ls -l 的結果給 a
echo $a # 別忘了,這么引用的話,ls 的結果中的所有空白部分都沒了(包括換行)
echo
echo "$a" # 這么引用就正常了,保留了空白
# (具體參閱章節"引用")
exit 0