Linux之bash變數和邏輯運算
什麼是變數?
變數最初來源於數學,指的是非固定的值可變化的數通常用拉丁字母表示。在計算機中變數它依舊指的是可變化的數,只不過表現形式有些變化。它指的是變數名+所指向的記憶體空間。
變數的特點
變數分強型別變數,與弱型別變數
強型別變數:變數需事先宣告且需提前定義其變數儲存格式
弱型別變數:不需事先宣告,不需定義變數儲存格式。
bash把所有變數統統視作字元型;bash中的變數無需事先宣告,相當於,把宣告和賦值過程同時實現。
變數名的命名規範:
變數名只能包含數字,字母和下劃線,而且不能以數字開頭。
其命名要求見名知義,命名機制遵循某種法則(駝峰法則)
bash的變數型別及其使用格式
本地變數,環境變數,區域性變數,位置引數變數,特殊變數
變數引用格式:$VAR、${VAR}
………………………………………………………………………………………………………………………
本地變數:作用域僅為當前shell程序
變數賦值:name=‘value’
value有如下引用型別
1、直接字串引用,格式:name="CHARS"
1 2 3 |
|
2、變數引用,格式:name=“$VAR”
1 2 3 |
|
3、命令引用,格式:name=`COMMAND` | name=$(COMMAND)
1 2 3 4 5 6 |
|
“”:弱引用,其中的變數引用會被替換為變數值;
1 2 3 |
|
‘’:強引用,其中的變數引用不會被替換為變數值,而保持原字串;
1 2 3 |
|
命令set用於顯示已定義的所有變數
撤銷已定義的變數,格式:unset 變數名
1 2 3 4 5 |
|
注:在剛接觸bash變數時特別容易搞錯的就是變數的使用格式,有時候該命令引用卻忘記加``或$(),還有就是強引用與弱引用的使用時機。
下面以例子說明本地變數的作用範圍,使用命令bash進入子shell
1 2 3 4 5 6 7 |
|
由實驗可知,作用域僅為當前shell程序。當然上面實驗做的不夠完善,因為並沒有演示在符父shell中其變數是否有效,大家可以在下面補充實驗去驗證。
………………………………………………………………………………………………………………………
環境變數:作用域為當前shell程序及子程序
變數賦值:
有四種賦值格式:
1、export name=value
2、name=value
export name
3、declare -x name=value
4、name=value
declare -x name
注:bash內嵌了許多環境變數(通常全為大寫字元),用於定義bash的工作環境
檢視/顯示環境變數 命令
export
1 2 3 4 5 6 |
|
declare -x
1 2 3 4 5 6 |
|
printenv
1 2 3 4 5 6 |
|
env
1 2 3 4 5 6 |
|
上面四個命令雖然顯示順序略有不同但是所包含的內容都是一樣的
1 2 3 4 5 6 7 8 |
|
撤銷環境變數
格式:unset VAR
下面通過例子驗證環境變數的作用範圍
1 2 3 4 5 6 |
|
………………………………………………………………………………………………………………………
區域性變數:作用域僅為某程式碼片段(通常用在函式)
因為函式還沒學到,這裡不舉例子
………………………………………………………………………………………………………………………
位置變數:當執行指令碼的shell程序傳遞的引數
$1,$2,...$(10)...:對應呼叫第1,第2...第10個引數
………………………………………………………………………………………………………………………
特殊變數:shell內建的特殊功用的變數
$#:傳遞給指令碼引數的個數
$*:傳遞給指令碼的所有引數;各引數讀成多個獨立字串
[email protected]:傳遞給指令碼的所有引數;各引數讀成一個完整的字串形式
$?:程式執行狀態返回值,0表示正確,1-255表示失敗
$0:表示命令本身
算術運算
Linux中的運算子主要有單目運算子和雙目運算子,運算子也有優先順序的高低之分。
運算子主要有以下這些:
優先順序 | 運算子 | 型別 | 說明 |
---|---|---|---|
13 | +、- | 單目 | 單目正、單目負。它們是單目運算子的正、負,而不是加、減。 |
12 | !、~ | 單目 | 邏輯非、按位取反或補碼。 |
11 | *、/、% | 雙目 | 乘、除、取模。 |
10 | +、- | 雙目 | 加、減。 |
9 | <<、>> | 雙目 | 按位左移、按位右移。 |
8 | <、<=、>、>= | 雙目 | 小於、小於等於、大於、大於等於。 |
7 | ==、!= | 雙目 | 等於、不等於。 |
6 | & | 雙目 | 按位與。 |
5 | ^ | 雙目 | 按位異或。 |
4 | | | 雙目 | 按位或。 |
3 | && | 雙目 | 邏輯與。 |
2 | || | 雙目 | 邏輯或。 |
1 | =、+=、-=、*=、/=、%=、&=、^=、|=、<<=、>>= | 雙目 | 賦值、運算且賦值。 |
說明:對於該表,數值越大,優先順序越高。故賦值運算子的優先順序最低。
注意: 小括號內的表示式的優先順序最高,會優先運算。因此,可以用小括號改變運算子的優先順序。
優先順序越高,會先進行運算;相同優先順序的運算子,按照先後順序順序運算。
--------------------- 本文來自 lamp_yang_3533 的CSDN 部落格 ,全文地址請點選:https://blog.csdn.net/lamp_yang_3533/article/details/70041211?utm_source=copy
在未學習bash中的算術運算之前如果要計算從1+...+10需要使用管道將其送入bc計算器來解決,
echo {1..10} | tr ' ' '+'| bc很麻煩。而使用bash中的算術運算則可以簡化程式碼。
bash中的算術運算格式:有很多種,本文只介紹常用的4種
1)let VAR=算術運算表示式
1 2 3 |
|
2)VAR=$[算術表示式]
1 2 3 |
|
3)VAR=$((算術表示式))
1 2 3 |
|
4)VAR=$(expr $ARG $OP $ARG2)
1 2 3 4 5 6 |
|
這種是呼叫expr命令計算後面運算表示式,它要求數值與運算子之間有空格,沒有空格則不進行計算,保持運算表示式原本模樣賦值給變數。
注:它與上述三種不同之處還有如果有乘法運算,乘法符號*在第四種裡面需要加\進行轉義。
以下為四種算術運算在乘法中的表現
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
第四種需要轉義,其他三種不需要。
邏輯運算子
邏輯卷標 | 表示意思 |
1. | 關於檔案與目錄的偵測邏輯卷標! |
-f | 常用!偵測『檔案』是否存在 eg: if [ -f filename ] |
-d | 常用!偵測『目錄』是否存在 |
-b | 偵測是否為一個『 block 檔案』 |
-c | 偵測是否為一個『 character 檔案』 |
-S | 偵測是否為一個『 socket 標籤檔案』 |
-L | 偵測是否為一個『 symbolic link 的檔案』 |
-e | 偵測『某個東西』是否存在! |
2. | 關於程式的邏輯卷標! |
-G | 偵測是否由 GID 所執行的程式所擁有 |
-O | 偵測是否由 UID 所執行的程式所擁有 |
-p | 偵測是否為程式間傳送資訊的 name pipe 或是 FIFO (老實說,這個不太懂!) |
3. | 關於檔案的屬性偵測! |
-r | 偵測是否為可讀的屬性 |
-w | 偵測是否為可以寫入的屬性 |
-x | 偵測是否為可執行的屬性 |
-s | 偵測是否為『非空白檔案』 |
-u | 偵測是否具有『 SUID 』的屬性 |
-g | 偵測是否具有『 SGID 』的屬性 |
-k | 偵測是否具有『 sticky bit 』的屬性 |
4. | 兩個檔案之間的判斷與比較 ;例如[ test file1 -nt file2 ] |
-nt | 第一個檔案比第二個檔案新 |
-ot | 第一個檔案比第二個檔案舊 |
-ef | 第一個檔案與第二個檔案為同一個檔案( link 之類的檔案) |
5. | 邏輯的『和(and)』『或(or)』 |
&& | 邏輯的 AND 的意思 |
|| | 邏輯的 OR 的意思 |
邏輯表示式
- test 命令
使用方法:test EXPRESSION
如:
[[email protected] ~]# test 1 = 1 && echo 'ok'
ok[[email protected] ~]# test -d /etc/ && echo 'ok'
ok[[email protected] ~]# test 1 -eq 1 && echo 'ok'
ok
[[email protected] ~]# if test 1 = 1 ; then echo 'ok'; fi
ok
注意:所有字元 與邏輯運算子直接用“空格”分開,不能連到一起。
- 精簡表示式
- [] 表示式
[[email protected] ~]# [ 1 -eq 1 ] && echo 'ok'
ok[[email protected] ~]# [ 2 < 1 ] && echo 'ok'
-bash: 2: No such file or directory
[[email protected] ~]# [ 2 \< 1 ] && echo 'ok'
[[email protected] ~]# [ 2 -gt 1 -a 3 -lt 4 ] && echo 'ok'
ok
[[email protected] ~]# [ 2 -gt 1 && 3 -lt 4 ] && echo 'ok'
-bash: [: missing `]'注意:在[] 表示式中,常見的>,<需要加轉義字元,表示字串大小比較,以acill碼 位置作為比較。 不直接支援<>運算子,還有邏輯運算子|| && 它需要用-a[and] –o[or]表示
[[email protected] ~]# [ 1 -eq 1 ] && echo 'ok'
- [[]] 表示式
ok[[email protected] ~]$ [[ 2 < 3 ]] && echo 'ok'
[[email protected] ~]$ [[ 2 < 3 && 4 > 5 ]] && echo 'ok'
ok
ok
注意:[[]] 運算子只是[]運算子的擴充。能夠支援<,>符號運算不需要轉義符,它還是以字串比較大小。裡面支援邏輯運算子:|| &&
三、效能比較
bash的條件表示式中有三個幾乎等效的符號和命令:test,[]和[[]]。通常,大家習慣用if [];then這樣的形式。而[[]]的出現,根據ABS所說,是為了相容><之類的運算子。以下是比較它們效能,發現[[]]是最快的。
$ time (for m in {1..100000}; do test -d .;done;)
real 0m0.658s
user 0m0.558s
sys 0m0.100s
$ time (for m in {1..100000}; do [ -d . ];done;)
real 0m0.609s
user 0m0.524s
sys 0m0.085s
$ time (for m in {1..100000}; do [[ -d . ]];done;)
real 0m0.311s
user 0m0.275s
sys 0m0.036s
不考慮對低版本bash和對sh的相容的情況下,用[[]]是相容性強,而且效能比較快,在做條件運算時候,可以使用該運算子。