shell腳本之算術運算和邏輯運算

目錄

   算術運算

   賦值運算

   邏輯運算

短路運算和異或

條件測試

數值測試

字符串測試

文件及其屬性測試

   存在性測試

存在性及類別測試

文件權限測試

文件特殊權限測試

文件大小測試

文件是否打開

雙目測試

   組合測試條件

   擴展

      read命令

      配置文件相關

      Bash退出任務

      關於$-變量

 

算術運算

Bash中我們可以進行算術運算,包括:+-*/%**,分別是加,減,乘,除,取餘,乘方。我們有六種方式,實現上面的運算:

(1) let var=算術表達式

(2) var=$[算術表達式]

(3) var=$((算術表達式))

(4) var=$(expr arg1 arg2 arg3 ...)

(5) declare i var = 數值

(6) echo ‘算術表達式’ | bc

有一點需要注意的是*在運算中需要轉譯即“\*

[root@CT71 ~]#let var1=1234
[root@CT71 ~]#var2=$[12+32]
[root@CT71 ~]#var3=$((12+12))
[root@CT71 ~]#var4=$( expr 1 + 2 + 3 + 4 )
[root@CT71 ~]#echo $var1 $var2 $var3 $var4
1234 44 24 10
[root@CT71 ~]#let var5=2**10
[root@CT71 ~]#let var6=2*10
[root@CT71 ~]#echo "3 * 4" | bc
12
[root@CT71 ~]#var7=$( expr 3 \* 5 )
[root@CT71 ~]#echo $var5 $var7
1024 15

除此以外bash中還有內建的隨機數生成器:$RANDOM0-32767

如:

   echo $[$RANDOM%50] 0-49之間隨機數

在算術運算和增強型賦值中,要使用letlet的具體用法請自行man let,它的功能是數字型運算和增強型賦值(下面會講到)

[root@CT71 ~]#echo $[$RANDOM%50]
12
[root@CT71 ~]#echo $[$RANDOM%50]
25
[root@CT71 ~]#echo $[$RANDOM%50]
39
[root@CT71 ~]#echo $[$RANDOM%50]
19
[root@CT71 ~]#

賦值

變量賦值,我們通常使用“=”,比如var=1234,就是把數值1234賦給var這個變量,此外我們還有其他的賦值方式,

增強型賦值方式:

   +=, -=, *=, /=, %=

   比如:

      var=2

let var+=23

這是var的值是25

除此以外,還有自增,自減:

   let var+=1

let var++

let var-=1

let var--

[root@CT71 ~]#var=2
[root@CT71 ~]#let var+=23
[root@CT71 ~]#echo $var
25
[root@CT71 ~]#let var++
[root@CT71 ~]#echo $var
26
[root@CT71 ~]#let var-=1
[root@CT71 ~]#echo $var
25
[root@CT71 ~]#

邏輯運算

我們在編寫腳本中無論如何都少不了邏輯判斷,我們通過邏輯判斷來進行我們需要進行的操作,完成我們需要的功能。現在我們先看一下最基本的邏輯功能。

true1false0

與:

1 1 = 1

1 0 = 0

0 1 = 0

0 0 = 0

:

1 1 = 1

1 0 = 1

0 1 = 1

0 0 = 0

這是我們最基本的邏輯與和或的關係,我們所有的邏輯判斷都是基於這些基本的邏輯判斷上的。在基本的邏輯中還有一個判斷那就是“非”或“!”代表的是一個意思即!1=0,!0=1

短路運算,異或

短路與(&&

   第一個爲0,結果必定爲0

第一個爲1,第二個必須要參與運算

短路或(||

   第一個爲1,結果必定爲1

第一個爲0,第二個必須要參與運算

異或(^

   異或的兩個值,相同爲假,不同爲真

A && B
  當A爲0時,不再執行B
  當A爲1時,還會執行B
A || B
  當A爲1時,不再執行B
  當A爲0時,繼續執行A
A ^ B
  當A == B,爲真
  當A != B,爲假

條件測試

linux腳本中,我們需要一些工具來幫助我們完成邏輯的判斷,通過判斷真假條件,在通過邏輯運算符來指定判斷出真假後我們需要進一步做些什麼,在linux中,有評估布爾聲明,以便用在條件執行中:

   若真,返回0

若假,返回1

我們一般的判斷命令如下:

   test expression

[exoression]

[[expression]]

對於這三種判斷方法,我們一般使用最多的是後兩種

注意: EXPRESSION前後必須有空白字符

示例:

[ "$A" == "$B" ] && echo "Strings are equal"

[ "$A" -eq "$B" ] && echo "Integers are equal"

[root@CT6 man]# A=23
[root@CT6 man]# B=24
[root@CT6 man]# [ $A -eq $B ] && echo "YES" || echo "NO"
NO
[root@CT6 man]# 

判斷一個變量是否設置,如果我們需要用一個變量,但不知道這個變來那個是否存在,我們可以使用-v來判斷這個變量是否存在。

[  -v VAR ] && echo “變量存在” || echo “變量不存在

[root@CT6 man]# set | grep "^A"
[root@CT6 man]# [ -v $A ] && echo "YES" || echo "NO"
YES
[root@CT6 man]# 

數值測試

在腳本中那我們很多時候需要判斷數字的大小,而linux中給我們提供了一種判斷數字大小的方法,配合條件判斷來進行使用:

-gt 是否大於

-ge 是否大於等於

-eq 是否等於

-ne 是否不等於

-lt 是否小於

-le 是否小於等於

示例:

   [ 23 –gt 22 ] && echo “true” || echo “false”

   [ 66 –ge 66 ] && echo “true” || echo “false”

[root@CT6 man]# [ 23 -gt 22 ] && echo "true" || echo "false" 
true
[root@CT6 man]# [ 66 -ge 66 ] && echo "true" || echo "false" 
true

字符串測試

   除了數值測試完,還有字符串測試,用於測試字符是否相同等。

  

== 是否等於

> ascii碼是否大於ascii

< 是否小於

!= 是否不等於

=~ 左側字符串是否能夠被右側的PATTERN所匹配

注意: 此表達式一般用於[[ ]]中;擴展的正則表達式

[root@CT6 man]# str1=LiuDehua
[root@CT6 man]# str2=LiuDehua
[root@CT6 man]# [ "$str1" == "$str2" ] && echo "=" || echo '!='
=
[root@CT6 man]# A=string_1234
[root@CT6 man]# [[ $A =~ [[:alpha:]]+[_][0-9]* ]] && echo "匹配" || echo "不匹配"
匹配

[root@CT6 man]# [[ $A =~ ^[[:digit:]] ]] && echo "匹配" || echo "不匹配"     
不匹配

-z "STRING 字符串是否爲空,空爲真,不空爲假

-n "STRING 字符串是否不空,不空爲真,空爲假

注意:用於字符串比較時的用到的操作數都應該使用引號

[root@CT6 man]# [ -z " " ] && echo "true" || echo "false"
false
[root@CT6 man]# [ -z "" ] && echo "true" || echo "false" 
true
[root@CT6 man]# [ -n "string" ] && echo "true" || echo "false" 
true
[root@CT6 man]# [ -n "" ] && echo "true" || echo "false"      
false

 

文件及屬性測試

在腳本中我們很多時候要對文件進行處理,那麼對文件的判斷就顯得尤爲重要,包括文件是否存在,文件的類型,文件的權限,文件的大小,文件的修改訪問時間等,我們通過一定的方式可以實現對文件的各種判斷,然後就可以實現我們的目的。

 

存在性測試

-a FILE:同-eand也是-a 一般使用-e

-e FILE: 文件存在性測試,存在爲真,否則爲假

[root@CT6 tmp]# echo 12345 >> test1.txt
[root@CT6 tmp]# ll
total 4
-rw-r--r--. 1 root root 6 Aug 15 15:04 test1.txt
[root@CT6 tmp]# [ -e test1.txt ] && echo "true" || echo "false"
true
[root@CT6 tmp]# rm test1.txt 
rm: remove regular file `test1.txt'? y
[root@CT6 tmp]# [ -e test1.txt ] && echo "true" || echo "false"
false

 

存在性及類別測試

-b FILE:是否存在且爲塊設備文件

-c FILE:是否存在且爲字符設備文件

-d FILE:是否存在且爲目錄文件

-f FILE:是否存在且爲普通文件

-h FILE -L FILE:存在且爲符號鏈接文件

-p FILE:是否存在且爲命名管道文件

-S FILE:是否存在且爲套接字文件

[root@CT6 tmp]# [ -b /dev/sda ] && echo "YES" || echo "NO"
YES
[root@CT6 tmp]# [ -d /dev ] && echo "YES" || echo "NO"     
YES
[root@CT6 tmp]# [ -h /lib64 ] && echo "YES" || echo "NO"     
NO

 

文件權限測試

-r FILE:是否存在且可讀

-w FILE: 是否存在且可寫

-x FILE: 是否存在且可執行

[du@CT6 ~]$ cd /tmp/
[du@CT6 /tmp]$ ll
total 0
---x--x--x. 1 root root 0 Aug 15 15:12 du1.doc
--w--w--w-. 1 root root 0 Aug 15 15:12 du2.doc
-rw-r--r--. 1 root root 0 Aug 15 15:12 du3.doc
-rw-r--r--. 1 root root 0 Aug 15 15:12 du4.doc
[du@CT6 /tmp]$ [ -r du1.doc  ] && echo "YES" || echo "NO"
NO
[du@CT6 /tmp]$ [ -r du3.doc ] && echo "YES" || echo "NO" 
YES
[du@CT6 /tmp]$ [ -w du1.doc ] && echo "YES" || echo "NO"  
NO
[du@CT6 /tmp]$ [ -w du3.doc ] && echo "YES" || echo "NO" 
NO
[du@CT6 /tmp]$ [ -w du2.doc ] && echo "YES" || echo "NO" 
YES

 

文件特殊權限測試

-u FILE:是否存在且擁有suid權限

-g FILE:是否存在且擁有sgid權限

-k FILE:是否存在且擁有sticky權限 

[root@CT6 tmp]# ll
total 0
-rwSr-Sr--. 1 root root 0 Aug 15 15:23 lianxi_1.doc
-rwSr--r--. 1 root root 0 Aug 15 15:23 lianxi_2.doc
-rw-r--r-T. 1 root root 0 Aug 15 15:23 lianxi_3.doc
-rw-r--r--. 1 root root 0 Aug 15 15:23 lianxi_4.doc
[root@CT6 tmp]# [ -u lianxi_2.doc ] && echo "YES" || echo "NO"
YES
[root@CT6 tmp]# [ -u lianxi_3.doc ] && echo "YES" || echo "NO" 
NO
[root@CT6 tmp]# [ -k lianxi_3.doc ] && echo "YES" || echo "NO" 
YES
[root@CT6 tmp]# [ -g lianxi_1.doc ] && echo "YES" || echo "NO"   
YES

 

文件大小測試

-s FILE: 是否存在且非空 

[root@CT6 tmp]# touch tty1
[root@CT6 tmp]# echo qqq > tty2
[root@CT6 tmp]# [ -s tty1 ] && echo "NOT empty" || echo "empty"
empty
[root@CT6 tmp]# [ -s tty2 ] && echo "NOT empty" || echo "empty" 
NOT empty

 

文件是否打開

-t fd: fd表示文件描述符是否已經打開且與某終端相關

-N FILE:文件自動上一次被讀取之後是否被修改過

-O FILE:當前有效用戶是否爲文件屬主

-G FILE:當前有效用戶是否爲文件屬組 

[root@CT6 tmp]# [ -O tty2 ] && echo "YES" || echo "NO"             
YES
[root@CT6 tmp]# [ -G tty2 ] && echo "YES" || echo "NO" 
YES
[root@CT6 tmp]# ll
total 8
-rw-r--r--. 1 root root    0 Aug 15 15:27 tty1
-rw-r--r--. 1 root root    4 Aug 15 15:27 tty2

 

雙目測試

FILE1 -ef FILE2: FILE1FILE2是否指向同一個設備上的相同inode

FILE1 -nt FILE2: FILE1是否新於FILE2mtime

FILE1 -ot FILE2: FILE1是否舊於FILE2

[root@CT6 tmp]# echo qqq > txt
[root@CT6 tmp]# ln txt txt_ln
[root@CT6 tmp]# ll
total 8
-rw-r--r--. 2 root root 4 Aug 15 15:31 txt
-rw-r--r--. 2 root root 4 Aug 15 15:31 txt_ln
[root@CT6 tmp]# [ txt -ef txt_ln ] && echo "YES" || echo "NO"
YES

[root@CT6 tmp]# touch old
[root@CT6 tmp]# touch new
[root@CT6 tmp]# [ old -ot new ] && echo "YES" || echo "NO"         
YES
[root@CT6 tmp]# [ old -nt new ] && echo "YES" || echo "NO" 
NO

組合測試條件

第一種方式:

COMMAND1 && COMMAND2 並且

COMMAND1 || COMMAND2 或者

! COMMAND

如: [[ -r FILE ]] && [[ -w FILE ]]

第二種方式:

EXPRESSION1 -a EXPRESSION2 並且

EXPRESSION1 -o EXPRESSION2 或者

! EXPRESSION

必須使用測試命令進行

兩種方法都能用,但是個人傾向於使用第二種,因爲看起來簡單,方便

[root@CT6 tmp]# echo "@@@@@@@" > tty
[root@CT6 tmp]# touch tty2
[root@CT6 tmp]# [ -f tty -a -s tty2 ] && echo "YES" || echo "No"
No

擴展

read命令

使用read來把輸入值分配給一個或多個shell變量

-p 指定要顯示的提示

-s 靜默輸入,一般用於密碼

-n N 指定輸入的字符長度N

-d ‘字符’ 輸入結束符

-t N TIMEOUTN

read 從標準輸入中讀取值,給每個單詞分配一個變量

所有剩餘單詞都被分配給最後一個變量

read -p “Enter a filename: “ FILE

一般用於腳本中

bash的配置文件

按生效範圍劃分,存在兩類:

全局配置:

/etc/profile

/etc/profile.d/*.sh

/etc/bashrc

個人配置:

~/.bash_profile

~/.bashrc

shell登錄兩種方式

交互式登錄:

(1)直接通過終端輸入賬號密碼登錄

(2)使用“su - UserName 切換的用戶

執行順序:/etc/profile --> /etc/profile.d/*.sh -->~/.bash_profile --> ~/.bashrc --> /etc/bashrc

非交互式登錄:

(1)su UserName

(2)圖形界面下打開的終端

(3)執行腳本

(4)任何其它的bash實例

執行順序: ~/.bashrc --> /etc/bashrc -->/etc/profile.d/*.sh

配置文件的兩種分類

按功能劃分,存在兩類:profile類和bashrc

profile類:爲交互式登錄的shell提供配置

全局: /etc/profile, /etc/profile.d/*.sh

個人: ~/.bash_profile

功用:

(1) 用於定義環境變量

(2) 運行命令或腳本

bashrc類:爲非交互式和交互式登錄的shell提供配置

全局: /etc/bashrc

個人: ~/.bashrc

功用:

(1) 定義命令別名和函數

(2) 定義本地變量

編輯配置文件生效

修改profilebashrc文件後需生效

兩種方法:

1重新啓動shell進程

2 . source

:

. ~/.bashrc

Bash退出任務

保存在~/.bash_logout文件中(用戶)

在退出登錄shell時運行

用於

創建自動備份

清除臨時文件

關於$-變量

h hashall,打開這個選項後, Shell 會將命令所在的路徑hash下來,避免每次都要查詢。通過set +hh選項關閉

i interactive-comments,包含這個選項說明當前的 shell是一個交互式的 shell。所謂的交互式shell,在腳本中, i選項是關閉的。

m monitor,打開監控模式,就可以通過Job control來控制進程的停止、繼續,後臺或者前臺執行等。

B braceexpand,大括號擴展

H history H選項打開,可以展開歷史列表中的命令,可以通過!感嘆號來完成,例如“!!”返回上最近的一個歷史命令,“!n”返回第 n 個歷史命令

[root@CT6 tmp]# echo $-
himBH
[root@CT6 tmp]# set +h
[root@CT6 tmp]# echo $-
imBH
[root@CT6 tmp]# set +B
[root@CT6 tmp]# echo $-
imH

 

 

 

發佈了52 篇原創文章 · 獲贊 5 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章