shell基礎之變量及表達式

本節內容

1. shell變量簡介

2. 定義變量

3. 使用變量

4. 修改變量的值

5. 單引號和雙引號的區別

6. 將命令的結果賦值給變量

7. 刪除變量

8. 變量類型

9. 特殊變量列表

10. 退出狀態

11. shell表達式與運算符

   11.1 條件表達式

   11.2 整數比較符

   11.3 字符串比較符

   11.4 文件測試

   11.5 布爾運算符

   11.6 邏輯判斷符

   11.7 整數運算

   11.8 其他運算工具

   11.9 shell括號用途總結

一、shell變量簡介

變量是任何一種編程語言都必不可少的組成部分,變量用來存放各種數據。腳本語言在定義變量時通常不需要指明類型,直接賦值就可以,Shell變量也遵循這個規則。

在Bash shell中,每一個變量的值都是字符串,無論你給變量賦值時有沒有使用引號,值都會以字符串的形式存儲。這意味着,Bash shell在默認情況下不會區分變量類型,即使你將整數和小數賦值給變量,它們也會被視爲字符串,這一點和大部分的編程語言不同。

二、定義變量

Shell 支持以下三種定義變量的方式:

variable=value

variable='value'

variable="value"

variable是變量名,value是賦給變量的值。如果value不包含任何空白符(例如空格、Tab縮進等),那麼可以不使用引號;如果value包含了空白符,那麼就必須使用引號包圍起來。使用單引號和使用雙引號也是有區別的,稍後我們會詳細說明。

注意,賦值號的周圍不能有空格,這可能和你熟悉的大部分編程語言都不一樣。

Shell變量的命名規範和大部分編程語言都一樣:

(1)變量名由數字、字母、下劃線組成;

(2)必須以字母或者下劃線開頭;

(3)不能使用 Shell 裏的關鍵字(通過 help 命令可以查看保留關鍵字)。

三、使用變量

使用一個定義過的變量,只要在變量名前面加美元符號$即可,如:

author="ken"

echo $author

echo ${author}

變量名外面的花括號{ }是可選的,加不加都行,加花括號是爲了幫助解釋器識別變量的邊界,比如下面這種情況:

skill="Java"

echo "I am good at ${skill}Script"

如果不給skill變量加花括號,寫成echo "I am good at $skillScript",解釋器就會把$skillScript當成一個變量(其值爲空),代碼執行結果就不是我們期望的樣子了。

推薦給所有變量加上花括號{ },這是個良好的編程習慣。

四、系統變量

在命令行提示符直接執行envset 查看系統或環境變量。env 顯示用戶環境變量,set 顯示Shell預先定義好的變量以及用戶變量。可以通過 export 導出成用戶變量。一些寫 Shell 腳本時常用的系統變量:

$SHELL

默認 Shell

$HOME

當前用戶家目錄

$IFS

內部字段分隔符

$LANG

默認語言

$PATH

默認可執行程序路徑

$PWD

當前目錄

$UID

當前用戶 ID

$USER

當前用戶

$HISTSIZE

歷史命令大小,可通過 HISTTIMEFORMAT 變量設置命令執行時間

$RANDOM(random隨機)

隨機生成一個0至32767的整數

$HOSTNAME

主機名

普通變量與臨時環境變量:

普通變量定義:VAR=value

臨時環境變量定義:export VAR=value

變量引用:$VAR

下面看下他們之間區別:

Shell 進程的環境變量作用域是 Shell 進程,當 export 導入到系統變量時,則作用域是 Shell 進程及其 Shell 子進程,另開shell無效。

五、修改變量的值

已定義的變量,可以被重新賦值,如:

url="http://www.baidu.com"

echo ${url}

url="http://www.sina.com"

echo ${url}

第二次對變量賦值時不能在變量名前加$,只有在使用變量時才能加$。

六、單引號和雙引號的區別

前面我們還留下一個疑問,定義變量時,變量的值可以由單引號' '包圍,也可以由雙引號" "包圍,它們到底有什麼區別呢?不妨以下面的代碼爲例來說明:

#!/bin/bash

url="http://c.biancheng.net"

website1='C語言中文網:${url}'

website2="C語言中文網:${url}"

echo $website1

echo $website2

運行結果:

C語言中文網:${url}

C語言中文網:http://c.biancheng.net

以單引號' '包圍變量的值時,單引號裏面是什麼就輸出什麼,即使內容中有變量和命令(命令需要反引起來)也會把它們原樣輸出。這種方式比較適合定義顯示純字符串的情況,即不希望解析變量、命令等的場景。

以雙引號" "包圍變量的值時,輸出時會先解析裏面的變量和命令,而不是把雙引號中的變量名和命令原樣輸出。這種方式比較適合字符串中附帶有變量和命令並且想將其解析後再輸出的變量定義。

建議:如果變量的內容是數字,那麼可以不加引號;如果真的需要原樣輸出就加單引號;其他沒有特別要求的字符串等最好都加上雙引號,定義變量時加雙引號是最常見的使用場景。

七、將命令的結果賦值給變量

Shell 也支持將命令的執行結果賦值給變量,常見的有以下兩種方式:

variable=`command`

variable=$(command)

第一種方式把命令用反引號包圍起來,反引號和單引號非常相似,容易產生混淆,所以不推薦使用這種方式;第二種方式把命令用$( )包圍起來,區分更加明顯,所以推薦使用這種方式。

例如,我創建了一個名爲 test 的文本文件。下面的代碼中,使用 cat 命令將 log.txt 的內容讀取出來,並賦值給一個變量,然後使用 echo 命令輸出。

 [root@ken ~]# echo "this is ken" > test

[root@ken ~]# mes=`cat test`

[root@ken ~]# echo $mes

this is ken

八、刪除變量

使用 unset 命令可以刪除變量。語法:

unset variable_name

變量被刪除後不能再次使用;unset 命令不能刪除只讀變量。

舉個例子:

#!/bin/bash

myUrl="http://see.xidian.edu.cn/cpp/u/xitong/"

unset myUrl

echo $myUrl

上面的腳本沒有任何輸出。

定義只讀變量

[root@ken ~]# name=ken

[root@ken ~]# readonly name

[root@ken ~]# echo $name

ken

[root@ken ~]# unset name

-bash: unset: name: cannot unset: readonly variable

九、變量類型

運行shell時,會同時存在三種變量:

1) 局部變量

局部變量在腳本或命令中定義,僅在當前shell實例中有效,其他shell啓動的程序不能訪問局部變量。

2) 環境變量

所有的程序,包括shell啓動的程序,都能訪問環境變量,有些程序需要環境變量來保證其正常運行。必要的時候shell腳本也可以定義環境變量。

3) shell變量

shell變量是由shell程序設置的特殊變量。shell變量中有一部分是環境變量,有一部分是局部變量,這些變量保證了shell的正常運行

十、特殊變量列表(shell變量)

變量

含義

$0

當前腳本的文件名

$n

傳遞給腳本或函數的參數。n是一個數字,表示第幾個參數。例如,第一個參數是$1,第二個參數是$2。

$#

傳遞給腳本或函數的參數個數。

$*

傳遞給腳本或函數的所有參數。

$?

上個命令的退出狀態,或函數的返回值。

$$

當前Shell進程ID。對於Shell腳本,就是這些腳本所在的進程ID。

例子:

#!/bin/bash

echo "File Name: $0"

echo "First Parameter : $1"

echo "First Parameter : $2"

echo "Quoted Values: $@"

echo "Quoted Values: $*"

echo "Total Number of Parameters : $#"

運行結果:

[root@ren5 ~]# bash test.sh name age

File Name: test.sh

First Parameter : name

First Parameter : age

Quoted Values: name age

Quoted Values: name age

Total Number of Parameters : 2

十一、退出狀態

$? 可以獲取上一個命令的退出狀態。所謂退出狀態,就是上一個命令執行後的返回結果。退出狀態是一個數字,一般情況下,大部分命令執行成功會返回 0,失敗返回 1。不過,也有一些命令返回其他值,表示不同類型的錯誤。

例子:

[root@ren5 ~]# echo ren

ren

[root@ren5 ~]# echo $?

0

[root@ren5 ~]# systemctl restart ab

Failed to restart ab.service: Unit not found.

[root@ren5 ~]# echo $?

5

十二、shell表達式與運算符

1、條件表達式

表達式

實例

[ expression ]

[ 1 -eq 1 ]

[[ expression ]]

[[ 1 -eq 1 ]]

test expression

test 1 -eq 1 ,等同於[ ]

[root@ren5 ~]# [ 1 -gt 2 ] && echo "this is true" || echo "this is false"

this is false

[root@ren5 ~]# [ 4 -gt 2 ] && echo "this is true" || echo "this is false"

this is true

注意:括號中的表達式前後都有空格,否則會報錯!

2、整數比較符

比較符

描述

實例

-eq, equal

等於

[ 1 -eq 1 ] 爲true

-ne, not equal

不等於

[ 1 -ne 1 ] 爲false

-gt, greate than

大於

[ 1 -gt 1 ] 爲false

-lt, lesser than

小於

[ 1 -lt 1 ] 爲false

-ge, greate or equal

大於或者等於

[ 1 -ge 1 ] 爲true

-le, lesser or equal

小於或者等於

[ 1 -le 1 ] 爲true

3、字符串比較符

運算符

描述

實例

==

等於

[ "a" == "a" ] 爲true

!=

不等於

[ "a" != "a" ] 爲false

-n

字符串長度不等於 0 爲真

VAR1=1;VAR2=""

[ -n "$VAR1" ]爲 true

[ -n "$VAR2" ]爲 false

-z

字符串長度等於0爲真

VAR1=1;VAR2=""

[ -z "$VAR1" ]爲false

[ -z "$VAR2" ]爲 true

注意:使用-n 判斷字符串長度時,變量要加雙引號,養成好習慣,字符串比較時都加上雙引號。

4、文件測試

測試符

描述

實例

-e

文件或者目錄存在爲真

[ -e path ] path 存在爲 true

-f

文件存在爲真

[ -f file_path ] 文件存在爲 true

-d

目錄存在爲真

[ -d dir_path ] 目錄存在爲 true

-r

有讀權限爲真

[ -r file_path ]file_path有讀權限爲真

-w

有寫權限爲真

[ -w file_path ]file_path有寫權限爲真

-x

有執行權限爲真

[ -x file_path ]file_path有執行權限爲真

5、布爾運算符

預算符

描述

實例

!

非關係,條件結果取反

[ ! 1 -eq 2 ]爲true

-a

和關係,在[]表達式中使用

[ 1 -eq 1 -a 2 -eq 2 ]爲true兩者都爲真才爲真

-o

或關係,在[]表達式中使用

[ 1 -eq 1 -o 2 -eq 1 ]爲true兩者有一真則爲真

6、邏輯判斷符

判斷符

描述

實例

&&

邏輯與,在[[]]表達式中

或判斷表達式是否爲真時使用

[[ 1 -eq 1 && 2 -eq 2 ]]爲 true

[ 1 -eq 1 ] && echo 'true',如果&&前面的表達式爲true則執行後面的

||

邏輯或,在[[]]表達式中

或判斷表達式是否爲真時使用

[[ 1 -eq 1 || 2 -eq 1 ]]爲 true

[ 1 -eq 2 ] || echo 'true',如果||前面的

表達式爲false則執行後面的

注意:[] 不支持以上兩個邏輯判斷符,應該使用布爾運算符

7、整數運算

運算符/表達式

描述/實例

+

加法

-

減法

*

乘法

/

除法

%

取餘

$(( ))

$((1+1))

$[ ]

$[ ]

8、其它運算工具

命令

描述

實例

let

賦值並運算,支持++、--

let VAR=(1+2)*3 ; echo $VAR

x=10 ; y=5

let x++;echo $x 每執行一次 x 加 1

let y--;echo $y 每執行一次 y 減 1

let x+=2 每執行一次 x 加 2

let x-=2 每執行一次 x 減 2

expr

乘法*需要加反斜槓轉義\*

expr 1 \* 2   運算符兩邊必須有空格

expr \( 1 + 2 \) \* 2  使用雙括號時要轉義

bc

計算器,支持浮點運算、平方等

bc 本身就是一個計算器,可直接輸入命令,進入解釋器

echo 1 + 2 |bc 將管道符前面標準輸出作爲 bc 的標準輸入

echo "1.2+2" |bc

scale      #小數點後保留多少位,默認是0位

echo “scale=2;4/3” |bc

9、ell括號用途總結

( )

用途1:在運算中,先計算小括號裏面的內容

用途2:數組

用途3:匹配分組

(( ))

用途1:表達式,不支持-eq這類的運算符。不支持-a和-o,支持<=、>=、<、>這類比較符和&&、||

用途2:C語言風格的for(( ))表達式

$( )

執行Shell命令,與反引號` `等效

$(( ))

用途1:簡單算數運算

用途2:支持三目運算符 $(( 表達式?數字:數字 ))

[ ]

條件表達式,裏面不支持邏輯判斷符

[[ ]]

條件表達式,裏面不支持-a和-o,不支持<=和>=比較符,支持-eq、<、>這類比較符。支持=~模式匹配,也可以不用雙引號也不會影響願意,比 [ ] 更加通用

$[ ]

簡單算數運算

{ }

對逗號(,)和點點(…)起作用,比如touch {1,2}創建1和2文件,touch {1…3}創建1、2、和3文件

${ }

用途1:引用變量

用途2:字符串處理

整數比較:
-eq 等於 if [ "$a" -eq "$b" ]
-ne 不等於 if [ "$a" -ne "$b" ]
-gt 大於 if [ "$a" -gt "$b" ]
-ge 大於等於 if [ "$a" -ge "$b" ]
-lt 小於 if [ "$a" -lt "$b" ]
-le 小於等於 if [ "$a" -le "$b" ]

< 小於(需要雙括號) (( "$a" < "$b" ))
<= 小於等於(...) (( "$a" <= "$b" ))
> 大於(...) (( "$a" > "$b" ))
>= 大於等於(...) (( "$a" >= "$b" ))

字符串比較:
= 等於 if [ "$a" = "$b" ]
== 與=等價
!= 不等於 if [ "$a" = "$b" ]
< 小於,在ASCII字母中的順序:
if [[ "$a" < "$b" ]]
if [ "$a" \< "$b" ] #需要對<進行轉義
> 大於

-z 字符串爲null,即長度爲0
-n 字符串不爲null,即長度

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章