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