[華為云在線課程][Shell腳本編程基礎][第二章Shell腳本語言的基本用法][3算術運算及測試][學習筆記]
格式化輸出printf
格式
printf "指定的格式" "文本1" "文本2"......
常用格式替換符
%s 字符串 %f 浮點格式 %b 相對應的參數中包含轉義字符時,可以使用此替換符進行替換,對應的轉義字符會被轉義 %c ASCII字符,即顯示對應參數的第一個字符 %d,%i 十進制整數 %o 八進制值 %u 不帶正負號的十進制值 %x 十六進制(a-f) %X 十六進制(A-F) %% 表示%本身
說明:%#s中的#數字代表此替換符中的輸出字符寬度,不足補空格,默認是右對齊,%-10s表示10個字符寬,-表示左對齊
常用轉義字符
\a 警告字符,通常為ASCII的BEL字符 \b 后退 \f 換頁 \n 換行 \r 回車 \t 水平制表符 \v 垂直制表符 \ 表示\本身
例子:
[root@localhost Code]# printf '%s\n' 1 2 3 4 1 2 3 4 [root@localhost Code]# printf '%f\n' 1 2 3 4 1.000000 2.000000 3.000000 4.000000 [root@localhost Code]# printf '%.2f\n' 1 2 3 4 1.00 2.00 3.00 4.00 [root@localhost Code]# printf '(%s)' 1 2 3 4;echo (1)(2)(3)(4) [root@localhost Code]# printf ' (%s) ' 1 2 3 4;echo (1) (2) (3) (4) [root@localhost Code]# printf ' (%s) \n' 1 2 3 4;echo (1) (2) (3) (4) [root@localhost Code]# printf '%s %s\n' 1 2 3 4 1 2 3 4 [root@localhost Code]# printf '%s %s %s\n' 1 2 3 4 1 2 3 4 #%-10s 表示寬度10個字符,左對齊 [root@localhost Code]# printf "%-10s %-10s %-4s %s \n" 姓名 性別 年齡 體重 小明 男 20 70 小紅 女 18 50 姓名 性別 年齡 體重 小明 男 20 70 小紅 女 18 50 #將十進制的17轉換成16進制數 [root@localhost Code]# printf "%X" 17;echo 11 #將十六進制C轉換為十進制 [root@localhost Code]# printf "%d\n" 0xC 12 [root@localhost Code]# VAR="Hello World";printf "3[31m%s3[0m\n" $VAR Hello World [root@localhost Code]# VAR="Hello World";printf "3[31m%s3[0m\n" "$VAR" Hello World
算術運算
shell允許在某些情況下對算術表達式進行求值,比如:let和declare內置命令,(())復合命令和算術拓展。求值以固定寬度的整數進行,不檢查溢出,盡管除以0被困并標記為錯誤。運算符及其優先級,關聯性和值與C語言相同。以下運算符列表分組為等優先級運算符級別。級別按降序排列優先。
注意:bash只支持整數,不支持小數
* / % multiplication,division,remainder,%表示取模,即取余數 + - addition,subtraction i++ i-- variable post-increment and post-decrement ++i --i variable pre-increment and post-increment = *= /= %= += -= <<= >>= &= ^= |= assignment - + unary minus and plus ! ~ logical and bitwise negation ** exponentiation << >> left and right bitwise shifts <= >= < > comparison == != equality and inequality & bitwise AND | bitwise OR ^ bitwise exclusive OR && logical AND || logical OR expr?expr:expr conditional operator expr1,expr2 comma
乘法符號有些場景中需要轉義
實現算術運算
(1)let var=算術表達式 (2)((var=算術表達式)) 和上面等價 (3)var=$[算術表達式] (4)var=$((算術表達式)) (5)var=$(expr arg1 arg2 arg3 ...) (6)declare -i var=數值 (7)echo '算術表達式' | bc
內建的隨機數生成器變量:
$RANDOM 取值范圍:0-32767
例子:
#生成 0-49 之間隨機數 echo $[$RANDOM%50] #隨機字體顏色 [root@localhost Code]# echo -e "\033[1;$[RANDOM%7+31]m hello \033[0m" hello
增強型賦值:
+= i+=10 相當于i=i+10 -= i-=j 相當于i=i-j *= /= %= ++ i++ ++i 相當于i=i+1 -- i-- --i 相當于i=i-1
格式:
let varOPERvalue
例子:
[root@localhost Code]# let i=10*2 [root@localhost Code]# echo $i 20 [root@localhost Code]# ((j=i+10)) [root@localhost Code]# echo $j 30
例子:
#自加3后賦值 [root@localhost Code]# let count+=3 [root@localhost Code]# i=10 [root@localhost Code]# let i+=20 [root@localhost Code]# echo $i 30 [root@localhost Code]# j=20 [root@localhost Code]# let i*=j [root@localhost Code]# echo $i 600
例子:
#自增,自減 [root@localhost Code]# unset i j;i=1;let j=i++;echo "i=$i,j=$j" i=2,j=1 [root@localhost Code]# unset i j;i=1;let j=++i;echo "i=$i,j=$j" i=2,j=2
例子:
[root@localhost Code]# expr 2 *3 expr: syntax error [root@localhost Code]# expr 2\* 3 expr: syntax error [root@localhost Code]# expr 2 \* 3 6
例子:
[root@localhost Code]# echo "scale=3;20/3"|bc 6.666
例子:
[root@localhost Code]# i=10 [root@localhost Code]# j=20 [root@localhost Code]# declare -i result=i*j [root@localhost Code]# echo $result 200
例子:計算雞兔同籠,上有35頭,下有94腳,問雞兔各有多少只?
[root@localhost Code]# cat chook_rabbit.sh #!/bin/bash HEAD=$1 FOOT=$2 RABBIT=$(((FOOT-HEAD-HEAD)/2)) CHOOK=$[HEAD-RABBIT] echo RABBIT:$RABBIT echo CHOOK:$CHOOK [root@localhost Code]# ./chook_rabbit.sh 35 94 RABBIT:12 CHOOK:23
邏輯運算
true,false
1,真 0,假 #注意,以上為二進制
&(與):與0相與,結果為0,和1相與,結果保留原值
1 & 1 = 1 1 & 0 = 0 0 & 1 = 0 0 & 0 = 0
|(或):和1相或結果為1,和0相或,結果保留原值
1 | 1 = 1 1 | 0 = 1 0 | 1 = 1 0 | 0 = 0
!(非)
! 1 = 0 ! true ! 0 = 1 ! false
^(異或)
#異或的兩個值,相同為假,不同為真。兩個數字X,Y異或得到結果Z,Z再和任意兩者之一X異或,將得出另一個值Y 0 ^ 0 = 0 0 ^ 1 = 1 1 ^ 0 = 1 1 ^ 1 = 0
例子:
[root@localhost Code]# true [root@localhost Code]# echo $? 0 [root@localhost Code]# false [root@localhost Code]# echo $? 1 [root@localhost Code]# !true true [root@localhost Code]# ! true [root@localhost Code]# echo $? 1 [root@localhost Code]# ! false [root@localhost Code]# echo $? 0
例子:變量互換
[root@localhost Code]# x=10;y=20;temp=$x;x=$y;y=$temp;echo x=$x,y=$y x=20,y=10 [root@localhost Code]# x=10;y=20;x=$[x^y];y=$[x^y];x=$[x^y];echo x=$x,y=$y x=20,y=10
短路運算
短路與
CMD1 短路與 CMD2 第一個CMD1結果為真 (1),第二個CMD2必須要參與運算,才能得到最終的結果 第一個CMD1結果為假 (0),總的結果必定為0,因此不需要執行CMD2
短路或
CMD1 短路或 CMD2 第一個CMD1結果為真 (1),總的結果必定為1,因此不需要執行CMD2 第一個CMD1結果為假 (0),第二個CMD2必須要參與運算,才能得到最終的結果
條件測試命令
條件測試:判斷某需求是否滿足,需要由測試機制來實現。專用的測試表達式需要由測試命令輔助完成測試過程,實現評估布爾聲明,以使用在條件性環境下進行執行
若真,則狀態碼變量$?返回0
若假,則狀態碼變量$?返回1
條件測試命令
test EXPRESSION
[EXPRESSION] #和test等價,建議使用[]
[[EXPRESSION]]相關于增強版的[]
注意:EXPRESSION前后必須有空白字符
幫助:
[root@localhost Code]# type [ [ is a shell builtin [root@localhost Code]# help [ [: [ arg... ] Evaluate conditional expression. This is a synonym for the "test" builtin, but the last argument must be a literal `]', to match the opening `['. [[ ... ]]: [[ expression ]] Execute conditional command. [root@localhost Code]# help test test: test [expr] Evaluate conditional expression. Exits with a status of 0 (true) or 1 (false) depending on the evaluation of EXPR. Expressions may be unary or binary. Unary expressions are often used to examine the status of a file. There are string operators and numeric comparison operators as well. The behavior of test depends on the number of arguments. Read the bash manual page for the complete specification.
變量測試
#判斷 NAME 變量是否定義 [ -v NAME ] #判斷 NAME 變量是否定義并且是名稱引用,bash 4.4新特性 [ -R NAME ]
例子:
[root@localhost Code]# unset x [root@localhost Code]# test -v x [root@localhost Code]# echo $? 1 [root@localhost Code]# unset x [root@localhost Code]# echo $? 0 [root@localhost Code]# x=10 [root@localhost Code]# test -v x [root@localhost Code]# echo $? 0 [root@localhost Code]# test -v y | echo $? 0 #注意[ ]需要空格,否則會報下面錯誤 [root@localhost Code]# [-v y] -bash: [-v: command not found [root@localhost Code]# [ -v y] -bash: [: missing `]' [root@localhost Code]# [ -v y ] [root@localhost Code]# echo $? 0
數值測試
-eq 是否等于 -ne 是否不等于 -gt 是否大于 -ge 是否大于等于 -lt 是否小于 -le 是否小于等于
例子:
[root@localhost Code]# i=10 [root@localhost Code]# j=8 [root@localhost Code]# [ $i -lt $j ] [root@localhost Code]# echo $? 1 [root@localhost Code]# [ $i -gt $j ] [root@localhost Code]# echo $? 0 [root@localhost Code]# [ i -gt j ] -bash: [: i: integer expression expected
算術表達式比較
== != <= >= < >
例子:
[root@localhost Code]# x=10;y=10;((x==y));echo $? 0 [root@localhost Code]# x=10;y=20;((x==y));echo $? 1 [root@localhost Code]# x=10;y=20;((x!=y));echo $? 0 [root@localhost Code]# x=10;y=10;((x!=y));echo $? 1
例子:
[root@localhost Code]# x=10;y=20;((x>y));echo $? 1 [root@localhost Code]# x=10;y=20;((x 字符串測試 test和[]用法 -z STRING 字符串是否為空,沒定義或空為真,不空為假 -n STRING 字符串是否不空,不空為真,空為假 STRING 同上 STRING1 = STRING2 是否等于,注意=前后有空格 STRING1 != STRING2 是否不等于 > ASCII碼是否大于ASCII碼 < ASCII碼是否小于ASCII碼 [[]]用法 [[ expression ]] 用法 == 左側字符串是否和右側的PATTERN相同 注意:此表達式用于[[ ]]中,PATTERN為通配符 =~ 左側字符串是否能夠被右側的正則表達式的PATTERN所匹配 注意:此表達式用于[[]]中,擴展的正則表達式 建議:當使用正則表達式或通配符使用[[]],其他情況一般使用[] 例子:使用[] [root@localhost Code]# unset str [root@localhost Code]# [ -z "$str" ] [root@localhost Code]# echo $? 0 [root@localhost Code]# str="" [root@localhost Code]# [ -z "$str" ] [root@localhost Code]# echo $? 0 [root@localhost Code]# str=" " [root@localhost Code]# [ -z "$str" ] [root@localhost Code]# echo $? 1 [root@localhost Code]# [ -z "$str" ] [root@localhost Code]# echo $? 1 [root@localhost Code]# [ "$str" ] [root@localhost Code]# echo $? 0 [root@localhost Code]# str1=hello [root@localhost Code]# str2=world [root@localhost Code]# [ $str1 = $str2 ] [root@localhost Code]# echo $? 1 [root@localhost Code]# str2=hello [root@localhost Code]# [ $str1 = $str2 ] [root@localhost Code]# echo $? 0 例子:在比較字符串時,建議變量放在""中 [root@localhost Code]# NAME="I love Linux" [root@localhost Code]# [ $NAME ] -bash: [: love: binary operator expected [root@localhost Code]# [ "$NAME" ] [root@localhost Code]# echo $? 0 [root@localhost Code]# [ I love Linux ] -bash: [: love: binary operator expected 例子:[[]]和通配符 [root@localhost Code]# FILE="a*" [root@localhost Code]# echo $FILE arg.sh a.sh [root@localhost Code]# [[ $FILE==a* ]] [root@localhost Code]# echo $? 0 [root@localhost Code]# FILE="ab" [root@localhost Code]# [[ $FILE==a* ]] [root@localhost Code]# echo $? 0 #[[]]中如果不想使用通配符*,只想表達*本身,可以用" "引起來,也可以使用轉義符 [root@localhost Code]# [[ FILE == a"*" ]] [root@localhost Code]# echo $? 1 [root@localhost Code]# [[ FILE == a\* ]] [root@localhost Code]# echo $? 1 #通配符? [root@localhost Code]# FILE=abc [root@localhost Code]# [[ $FILE == ??? ]] [root@localhost Code]# echo $? 0 [root@localhost Code]# FILE=abcd [root@localhost Code]# [[ $FILE == ??? ]] [root@localhost Code]# echo $? 1 #通配符 [root@localhost Code]# NAME="linux" [root@localhost Code]# [[ "$NAME" == linux* ]] [root@localhost Code]# echo $? 0 [root@localhost Code]# [[ "$NAME" == "linux*" ]] [root@localhost Code]# echo $? 1 [root@localhost Code]# NAME="linux*" [root@localhost Code]# [[ "$NAME" == "linux*" ]] [root@localhost Code]# echo $? 0 #結論:[[ == ]] == 右側的 * 作為通配符,不要加"",只想作為*,需要加""或者轉義 例子:判斷合理的考試成績 [root@localhost Code]# SCORE=101 [root@localhost Code]# [[ $SCORE =~ 100|[0-9]{1,2} ]] [root@localhost Code]# echo $? 0 [root@localhost Code]# [[ $SCORE =~ ^(100|[0-9]{1,2})$ ]] [root@localhost Code]# echo $? 1 [root@localhost Code]# SCORE=10 [root@localhost Code]# [[ $SCORE =~ ^(100|[0-9]{1,2})$ ]] [root@localhost Code]# echo $? 0 [root@localhost Code]# SCORE=abc [root@localhost Code]# [[ $SCORE =~ ^(100|[0-9]{1,2})$ ]] [root@localhost Code]# echo $? 1 文件測試 存在性測試 -a FILE 同 -e -e FILE 文件存在性測試,存在為真,否則為假 -b FILE 是否存在且為塊設備文件 -c FILE 是否存在且為字符設備文件 -d FILE 是否存在且為目錄文件 -f FILE 是否存在且為普通文件 -h FILE 或 -L FILE 是否存在且為符號鏈接文件 -p FILE 是否存在且為命名管道文件 -s FILE 是否存在且為套接字文件 例子: #文件是否存在 [root@localhost Code]# [ -a /home/hello/Code/hello ] [root@localhost Code]# echo $? 1 [root@localhost Code]# [ -a /home/hello/Code/a.sh ] [root@localhost Code]# echo $? 0 文件權限測試: -r FILE 是否存在且可讀 -w FILE 是否存在且可寫 -x FILE 是否存在且可執行 -u FILE 是否存在且擁有suid權限 -g FILE 是否存在且擁有sgid權限 -k FILE 是否存在且擁有sticky權限 注意:最終結果由用戶對文件的實際權限決定,而非文件屬性決定。 例如將寫權限關閉,但是root用戶還是能執行操作。 文件屬性測試 -s FILE 是否存在且非空 -t fd fd 文件描述符是否在某終端中打開 -N FILE 文件自從上一次被讀取之后是否被修改過 -O FILE 當前有效用戶是否為文件屬主 -G FILE 當前有效用戶是否為文件屬組 FILE1 -ef FILE2 FILE1是否是FILE2的硬連接 FILE1 -nt FILE2 FILE1是否新于FILE2(mtime) FILE1 -ot FILE2 FILE1是否舊于FILE2 關于 () 和 {} (CMD1;CMD2;…)和{CMD1;CMD2;…;} 都可以將多個命令組合在一起,批量執行 man bash ( list )會開啟子shell,并且list中變量賦值及內部命令執行后,將不再影響后續的環境 幫助查看:man bash 搜索(list) { list; }不會開啟子shell,在當前shell中運行,會影響當前shell環境 幫助查看:man bash 搜索{ list; } 組合測試條件 第一種方式 [] [ EXPRESSION1 -a EXPRESSION2 ] 并且,EXPRESSION1和EXPRESSION2都是真,結果才真 [ EXPRESSION1 -o EXPRESSION2 ] 或者,EXPRESSION1和EXPRESSION2只要一個為真,結果就為真 [ ! EXPRESSION ] 取反 說明:-a 和 -o 需要使用測試命令進行,[[]]不支持 第二種方式 COMMAND1 && COMMAND2 并且,短路與,代表條件性的AND THEN 如果COMMAND1成功,將執行COMMAND2,否則,將不執行COMMAND2 COMMAND1 || COMMAND2 或者,短路或,代表條件性的OR THEN 如果COMMAND1成功,將不執行COMMAND2,否則,將執行COMMAND2 !COMMAND 非,取反 注意:如果&&和||混合使用,&&要在前,||要在后 #Linux版俄羅斯輪盤 [ $[RANDOM%6] -eq 0 ] && rm -rf /* || echo "You are lucky" 使用read命令來接受輸入 使用read來把輸入值分配給一個或多個shell變量,read從標準輸入中讀取值,給每個單詞分配一個變量,所有剩余單詞都被分配給最后一個變量,如果變量名沒有指定,默認標準輸入的值賦值給系統內置變量REPLY 格式: read [options] [name,...] 常見選項: -p 指定要顯示的提示 -s 靜默輸入,一般用于密碼 -n N 指定輸入的字符長度N -d '字符' 輸入結束符 例子: [root@localhost Code]# read x y z <<< "I love you" [root@localhost Code]# echo $x I [root@localhost Code]# echo $y love [root@localhost Code]# echo $z you 例子:判斷用戶輸入的是否為YES [root@localhost Code]# cat yesorno.sh #!/bin/bash read -p "Please input yes or no: " input answer=`echo $input|tr 'A-Z' 'a-z'` [ $answer = 'yes' -o $answer = 'y' ] && echo YES [ $answer = 'no' -o $answer = 'n' ] && echo NO [root@localhost Code]# cat yesorno2.sh #!/bin/bash read -p "Please input yes or no: " input [[ $input =~ ^([Yy][Ee][Ss]|[Yy])$ ]] && echo YES [[ $input =~ ^([Nn][Oo]|[Nn])$ ]] && echo NO Linux Shell
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。