bash-shell高级编程--操作符与相关主题
操作符與相關(guān)主題
操作符
賦值
變量賦值,初始化或者修改變量的值
=
通用賦值操作符,可用于算術(shù)和字符串賦值。
var=12 car=bmw # 在=號(hào)后面不能出現(xiàn)空白字符的不要混淆=賦值操作符與=測(cè)試操作符
# = 在這里是測(cè)試操作符 if [ "$string1" = "$string2" ] # if [ "X$string1" = "X$string2" ] 是一種更安全的做法, # 這樣可以防止兩個(gè)變量中的一個(gè)為空所產(chǎn)生的錯(cuò)誤. # (字符"X"作為前綴在等式兩邊是可以相互抵消的.) thencommand fi算術(shù)操作符
+
加法計(jì)算
-
減法計(jì)算
*
乘法計(jì)算
/
除法計(jì)算
**
冪運(yùn)算
# 在Bash, 版本2.02, 中開(kāi)始引入了"**" 冪運(yùn)算符.let "z=5**3" echo "z = $z" # z = 125%
模運(yùn)算,或者說(shuō)是求余運(yùn)算
求最大公約數(shù)
#!/bin/bash # gcd.sh: 最大公約數(shù) #使用Euclid的算法# 兩個(gè)整數(shù)的"最大公約數(shù)" (gcd), #+ 就是兩個(gè)整數(shù)所能夠同時(shí)整除的最大的數(shù).# Euclid算法采用連續(xù)除法. # 在每一次循環(huán)中, #+ 被除數(shù) <--- 除數(shù) #+ 除數(shù) <--- 余數(shù) #+ 直到 余數(shù) = 0. #+ 在最后一次循環(huán)中, gcd = 被除數(shù). # # 關(guān)于Euclid算法的更精彩的討論, 可以到 #+ Jim Loy的站點(diǎn), http://www.jimloy.com/number/euclids.htm.# ------------------------------------------------------ # 參數(shù)檢查 ARGS=2 E_BADARGS=65if [ $# -ne "$ARGS" ] thenecho "Usage: `basename $0` first-number second-number"exit $E_BADARGS fi # ------------------------------------------------------gcd () {dividend=$1 # 隨意賦值.divisor=$2 #+ 在這里, 哪個(gè)值給的大都沒(méi)關(guān)系. # 為什么沒(méi)關(guān)系?remainder=1 # 如果在循環(huán)中使用了未初始化的變量, #+ 那么在第一次循環(huán)中, #+ 它將會(huì)產(chǎn)生一個(gè)錯(cuò)誤消息.until [ "$remainder" -eq 0 ]do let "remainder = $dividend % $divisor" dividend=$divisor # 現(xiàn)在使用兩個(gè)最小的數(shù)來(lái)重復(fù). divisor=$remainderdone # Euclid的算法 } # Last $dividend is the gcd. gcd $1 $2 echo; echo "GCD of $1 and $2 = $dividend"; echo # Exercise : # -------- # 檢查傳遞進(jìn)來(lái)的命令行參數(shù)來(lái)確保它們都是整數(shù). #+ 如果不是整數(shù), 那就給出一個(gè)適當(dāng)?shù)腻e(cuò)誤消息并退出腳本. exit 0執(zhí)行結(jié)果
andrew@andrew:/work/bash/src$ bash gcd.sh 2345 56GCD of 2345 and 56 = 7+=
“加-等于” (把變量的值增加一個(gè)常量然后再把結(jié)果賦給變量)let "var += 5" var 變量的值會(huì)在原來(lái)的基礎(chǔ)上加 5 .
-=
“減-等于” (把變量的值減去一個(gè)常量然后再把結(jié)果賦給變量)
*=
“乘-等于” (先把變量的值乘以一個(gè)常量的值, 然后再把結(jié)果賦給變量)
let "var *= 4" var 變量的結(jié)果將會(huì)在原來(lái)的基礎(chǔ)上乘以 4 .
/=
“除-等于” (先把變量的值除以一個(gè)常量的值, 然后再把結(jié)果賦給變量)
%=
“取模-等于” (先對(duì)變量進(jìn)行模運(yùn)算, 即除以一個(gè)常量取模, 然后把結(jié)果賦給變量)
算術(shù)操作符經(jīng)常會(huì)出現(xiàn)在 expr或let表達(dá)式中.
使用算術(shù)操作符
#!/bin/bash # 使用10種不同的方法計(jì)數(shù)到11. n=1; echo -n "$n "let "n = $n + 1" # let "n = n + 1" 也可以. echo -n "$n ": $((n = $n + 1)) # ":" 是必需的, 因?yàn)槿绻麤](méi)有":"的話, #+ Bash將會(huì)嘗試把"$((n = $n + 1))"解釋為一個(gè)命令. echo -n "$n "(( n = n + 1 )) # 上邊這句是一種更簡(jiǎn)單方法. # 感謝, David Lombard, 指出這點(diǎn). echo -n "$n "n=$(($n + 1)) echo -n "$n ": $[ n = $n + 1 ] # ":" 是必需的, 因?yàn)槿绻麤](méi)有":"的話, #+ Bash將會(huì)嘗試把"$[ n = $n + 1 ]"解釋為一個(gè)命令. # 即使"n"被初始化為字符串, 這句也能夠正常運(yùn)行. echo -n "$n "n=$[ $n + 1 ] # 即使"n"被初始化為字符串, 這句也能夠正常運(yùn)行. #* 應(yīng)該盡量避免使用這種類(lèi)型的結(jié)構(gòu), 因?yàn)樗呀?jīng)被廢棄了, 而且不具可移植性. echo -n "$n " # echo輸出時(shí)不輸出最后的回車(chē) # 現(xiàn)在來(lái)一個(gè)C風(fēng)格的增量操作.let "n++" # let "++n" 也可以. echo -n "$n "(( n++ )) # (( ++n ) 也可以. echo -n "$n ": $(( n++ )) # : $(( ++n )) 也可以. echo -n "$n ": $[ n++ ] # : $[ ++n ]] 也可以. echo -n "$n " echo exit 0執(zhí)行結(jié)果
andrew@andrew:/work/bash/src$ bash algroth.sh 1 2 3 4 5 6 7 8 9 10 11在bash中的整型變量事實(shí)上是一個(gè)有符號(hào)的long(32-bit)整型值,所表示的范圍是-2147483648到2147483647。如果超過(guò)這個(gè)范圍進(jìn)行算術(shù)操作的話,那么將不會(huì)得到你期望的結(jié)果。
bash中不能直接進(jìn)行浮點(diǎn)型計(jì)算,要是需要進(jìn)行浮點(diǎn)型計(jì)算,需要在腳本中使用bc,這個(gè)命令可以進(jìn)行浮點(diǎn)型運(yùn)算,或者調(diào)用數(shù)學(xué)庫(kù)函數(shù)
位操作符
<<
左移一位
<<=
“左移-賦值”
let "var <<= 2"
這句的結(jié)果就是變量 var 左移 2 位(就是乘以 4 )
>>
右移一位
>>=
右移-賦值
&
按位與
&=
“按位與-賦值”
|
按位或
|=
“按位或-賦值”
~
按位反
!
按位非
^
按位異或XOR
^=
“按位異或-賦值”
邏輯操作符
&&
與(邏輯)
||
或(邏輯)
使用&& 和 || 進(jìn)行混合條件測(cè)試
#!/bin/basha=24 b=47# 如果a==24 并且b==47 則條件成立 if [ "$a" -eq 24 ] && [ "$b" -eq 47 ] thenecho "Test #1 succeeds." elseecho "Test #1 fails." fi# ERROR: 在單括號(hào)中不能使用 && 但是在雙括號(hào)中能使用 if [ "$a" -eq 24 && "$b" -eq 47 ] #+嘗試運(yùn)行' [ "$a" -eq 24 ' #+因?yàn)闆](méi)找到匹配的']'所以失敗了. # # 注意: if [[ $a -eq 24 && $b -eq 24 ]] 也能正常運(yùn)行. # 雙中括號(hào)的if-test結(jié)構(gòu)要比 #+ 單中括號(hào)的if-test結(jié)構(gòu)更加靈活. #(在第17行"&&"與第6行的"&&"具有不同的含義.)if [ "$a" -eq 98 ] || [ "$b" -eq 47 ] thenecho "Test #2 succeeds." elseecho "Test #2 fails." fi# -a和-o選項(xiàng)提供了 #+ 一種可選的混合條件測(cè)試的方法.if [ "$a" -eq 24 -a "$b" -eq 47 ] thenecho "Test #3 succeeds." elseecho "Test #3 fails." fiif [ "$a" -eq 98 -o "$b" -eq 47 ] thenecho "Test #4 succeeds." elseecho "Test #4 fails." fia=rhino b=crocodile if [ "$a" = rhino ] && [ "$b" = crocodile ] thenecho "Test #5 succeeds." elseecho "Test #5 fails." fiexit 0使用shellcheck工具對(duì)該腳本進(jìn)行檢測(cè)
andrew@andrew:/work/bash/src$ shellcheck if_else.sh In if_else.sh line 15: if [ "$a" -eq 24 && "$b" -eq 47 ] ^-- SC1073: Couldn't parse this if expression.In if_else.sh line 57: exit 0^-- SC1050: Expected 'then'.^-- SC1072: Expected 'then'.. Fix any mentioned problems and try again.提示腳本的第15行出現(xiàn)問(wèn)題,看腳本的第15行會(huì)發(fā)現(xiàn)
if [ "$a" -eq 24 && "$b" -eq 47 ]腳本在單括號(hào)中使用了&&
&&和||操作符也可以用在算術(shù)上下文中.
andrew@andrew:~$ echo $(( 1 && 2 )) $((3 && 0)) $((4 || 0)) $((0 || 0)) 1 0 1 0,
,號(hào)操作符,逗號(hào)操作符可以鏈接兩個(gè)或多個(gè)算術(shù)運(yùn)算,所有的操作都會(huì)被運(yùn)行,但是只會(huì)返回最后的操作的結(jié)果
let "t1 = ((5 + 3, 7 - 1, 15 - 4))" echo "t1 = $t1" # t1 = 11 let "t2 = ((a = 9, 15 / 3))" # 設(shè)置"a"并且計(jì)算"t2". echo "t2 = $t2 a = $a"# t2 = 5 a = 9數(shù)字常量
shell腳本在默認(rèn)情況下,都是把數(shù)字作為10進(jìn)制來(lái)處理,除非這個(gè)數(shù)字采用了特殊的標(biāo)記或者前綴。如果數(shù)字以0開(kāi)頭的話那么就是8進(jìn)制,如果數(shù)字以0x開(kāi)頭的話那么就是16進(jìn)制數(shù),如果數(shù)字中間嵌入了#的話,那么就被認(rèn)為是BASE#NUMBER形式的標(biāo)記法。
數(shù)字常量表示法
#!/bin/bash # numbers.sh: 幾種不同數(shù)制的數(shù)字表示法.# 10進(jìn)制: 默認(rèn)情況 let "dec = 32" echo "decimal number = $dec" # 32 # 這沒(méi)什么特別的.# 8進(jìn)制: 以'0'(零)開(kāi)頭 # 八進(jìn)制的 32 剛好是 3*8 + 2 = 26 let "oct = 032" echo "octal number = $oct" # 26 # 表達(dá)式結(jié)果是用10進(jìn)制表示的. # ---------------------------# 16進(jìn)制: 以'0x'或者'0X'開(kāi)頭的數(shù)字 # 十六進(jìn)制的 0x32就是60 let "hex = 0x32" echo "hexadecimal number = $hex" # 50 # 表達(dá)式結(jié)果是用10進(jìn)制表示的.# 其他進(jìn)制: BASE#NUMBER # BASE的范圍在2到64之間. # NUMBER的值必須使用BASE范圍內(nèi)的符號(hào)來(lái)表示, 具體看下邊的示例.# 二進(jìn)制的 let "bin = 2#111100111001101" echo "binary number = $bin" # 31181let "b32 = 32#77" echo "base-32 number = $b32" # 231let "b64 = 64#@_" echo "base-64 number = $b64" # 4031 # 這個(gè)表示法只能工作于受限的ASCII字符范圍(2 - 64). # 10個(gè)數(shù)字 + 26個(gè)小寫(xiě)字母 + 26個(gè)大寫(xiě)字符 + @ + _echoecho $((36#zz)) $((2#10101010)) $((16#AF16)) $((53#1aA))# 1295 170 44822 3375# 重要的注意事項(xiàng): # --------------- # 使用一個(gè)超出給定進(jìn)制的數(shù)字的話, #+ 將會(huì)引起一個(gè)錯(cuò)誤.let "bad_oct = 081" # (部分的) 錯(cuò)誤消息輸出: # bad_oct = 081: value too great for base (error token is "081") #Octal numbers use only digits in the range 0 - 7.exit 0 andrew@andrew:/work/bash/src$ andrew@andrew:/work/bash/src$ shellcheck numbers.sh andrew@andrew:/work/bash/src$ bash numbers.sh decimal number = 32 octal number = 26 hexadecimal number = 50 binary number = 31181 base-32 number = 231 base-64 number = 40311295 170 44822 3375 numbers.sh: 行 56: let: bad_oct = 081: 數(shù)值太大不可為算數(shù)進(jìn)制的基 (錯(cuò)誤符號(hào)是 "081")總結(jié)
以上是生活随笔為你收集整理的bash-shell高级编程--操作符与相关主题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 大数据时代网络安全必读
- 下一篇: 作者:郭海红(1987-),女,中国医