shell_02基本操作 算術操作(expr) --在bash中只能做整數的運算+ 加- 減* 乘/ 除(取整)% 取餘 $(())$[] expr 60 \* 60 \* 24expr 60 \* 60 \* 7expr 1 + 1expr 1 * 1expr $( 10 + 10 ) / 10expr $((10 + 10)) / 10expr 10 % 3 # expr $RANDOM % 10 # let "v=2**16"# echo $v65536 退出狀態 在Linux系統中,每當命令執行完成後,系統都會返回一個退出狀態。該退出狀態用一整數值表示,用於判斷命令運行正確與否。若退出狀態值為0,表示命令運行成功若退出狀態值不為0時,則表示命令運行失敗最後一次執行的命令的退出狀態值被儲存在內建變數“$?”中,所以可以通過echo語句進行測試命令是否運行成功0 表示運行成功,程式執行未遇到任何問題1~125 表示運行失敗,指令碼命令、系統命令錯誤或參數傳遞錯誤126 找到了該命令但無法執行>128 命令被系統強制結束 條件運算式:test命令用途:測試特定的運算式是否成立,當條件成立時,命令執行後的傳回值$?為0,否則為其他數值格式: test 條件運算式 [ 條件運算式 ] test可以測試表示有哪些:1、檔案狀態2、字串的比對3、整數的比對4、多條件組合(|| && !)(-a -o !) ------------------------------------------------------#man test -a = && -o = || ! 單個條件: [ ! 1 -eq 1 ] 兩個值的結果再取反 ,驚嘆號的優先順序別最低,除非加括弧;! [ 1 -eq 1 ] 多個條件:[ 1 -eq 1 -a 10 -eq 10 ] = [ 1 -eq 1 ] && [ 10 -eq 10 ] 兩個條件成立,才正確; [ 1 -eq 1 -o 10 -eq 10 ] = [ 1 -eq 1 ] || [ 10 -eq 10 ] 取或; [ 1 -eq 1 -o 10 -eq 10 -o 1 -eq 1 ] = [ 1 -eq 1 ] || [ 10 -eq 10 ] || [ 1 -eq 1 ]-----------------------------------------------------# test 1 = 1# echo $?0 # [ 1 = 1 ] --[] = test --單條件# echo $?0 # [ 1 = 1 ] && echo YESYES # [ 1 = 2 ] && echo YES --無返回 || -o or&& -a and! 條件的組合: [ 1 = 1 -a 1 = 2 ] 與組合 [ 1 = 1 ] && [ 1 = 2 ] 與組合 [ 1 = 1 ] || [ 1 = 2 ] 或組合 [ 1 = 1 -o 1 = 2 ] 或組合邏輯運算子1)邏輯運算子主要包括邏輯非、邏輯與、邏輯或運算子,具體描述如下表所示:邏輯操作符 描述 !expression 如果expression為假,則測試結果為真expression1 a expression2 如果expression1和expression同時為真,則測試結果為真expression1 o expression2 如果expression1和expression2中有一個為真,則測試條件為真 2)下表是邏輯運算子的“真假表”,其中expr1和expr2為運算式,用於描述了一個測試條件。 expr1 expr2 !expr1 ! expr2 expr1 a expr2 expr1 o expr2 真 真 假 假 真 真 真 假 假 真 假 真 假 真 真 假 假 真 假 假 真 真 假 假 [ ! 1 -eq 1 ] 盡量用 -eq 不用 = ; -eq 當整數處理; = 當字串處理;shell的內部處理;<字串或串(String)是由數字、字母、底線組成的一串字元。一般記為 s=“a1a2···an”(n>=0)。它是程式設計語言中表示文本的資料類型。> 常見的運算式類型1、測試檔案狀態2、字串比較3、整數值比較4、邏輯測試 檔案運算式: -a file 檔案是否存在# [ -a /etc ] && echo YES --目錄YES # [ -a /etc/passwd ] && echo YES --檔案YES # [ -a /etc/passwdddd ] && echo YES --無傳回值 ------------------------------------- -b file 檔案存在,而且是裝置檔案# [ -b /dev/sda ] && echo YESYES # [ -b /dev/passwd ] && echo YES --無傳回值 ------------------------------------- -c file 檔案存在,而且字元檔案# [ -c /dev/tty1 ] && echo YESYES # [ -c /etc/passwd ] && echo YES --無傳回值 ------------------------------------- -d file 檔案存在,而且類型是目錄# [ -d /etc/ ] && echo YESYES # [ -d /etc/passwd ] && echo YES --無傳回值------------------------------------- -e file 檔案的真實檔案是否存在。------------------------------------- -f file 檔案存在,而且常規檔案# [ -f /etc/passwd ] && echo YESYES # [ -f /etc/ ] && echo YES --無傳回值------------------------------------- -g file 檔案存在,而且設定強制位 # find / -perm -2000 --尋找系統中哪些檔案擁有強制位# [ -g /usr/bin/wall ] && echo YESYES# [ -g /usr/bin/vim ] && echo YES --無傳回值 ------------------------------------- -h file 檔案存在,而且是軟連結檔案------------------------------------- -k file 擁有粘滯位目錄[ -k /tmp ] && echo YESYES # [ -k /root ] && echo YES --無傳回值 ------------------------------------- -p file 測試管道檔案 # find / -type p --尋找系統中有哪些管道檔案# [ -p /tmp/vmware-root.2 ] && echo YESYES# [ -p /etc/passwd ] && echo YES --無傳回值 ------------------------------------- -r file 檔案存在,而且目前使用者對此擁有讀的許可權# su - user01 --切換到普通使用者$ [ -r /etc/passwd ] && echo YESYES $ [ -r /etc/shadow ] && echo YES --無傳回值 ------------------------------------- -s file 檔案存在,而且檔案內容非空# touch /opt/a.txt# [ -s /opt/a.txt ] && echo YES --無傳回值 # [ -s /etc/passwd ] && echo YESYES ------------------------------------- -t 檔案描述符(FD)是在一個終端開啟的------------------------------------- -u file 擁有suid的檔案# find / -perm -4000# [ -u /bin/mount ] && echo YESYES # [ -u /etc/passwd ] && echo YES --無傳回值 ------------------------------------- -w file 測試檔案寫入權限# [ -w /etc/passwd ] && echo YESYES# [ -w /etc/ ] && echo YESYES $ [ -w /etc/passwd ] && echo YES --無傳回值------------------------------------- -x file 測試是否擁有執行許可權$ [ -x /bin/ls ] && echo YESYES $ [ -x /sbin/unix_update ] && echo YES --無傳回值 -------------------------------------下面為大寫字母:------------------------------------- -O file 測試檔案擁有者是否是目前使用者$ touch /tmp/a$ [ -O /tmp/a ] && echo YESYES $ [ -O /etc/passwd ] && echo YES --無傳回值 ------------------------------------- -G file 對此檔案屬組(主組)$ touch /tmp/a$ [ -G /tmp/a ] && echo YESYES $ [ -G /etc/passwd ] && echo YES --無傳回值 ------------------------------------- -L file True if file exists and is a symbolic link. --檔案存在而且是軟連結------------------------------------- -S file 測試對象是否是socket# [ -S /dev/log ] && echo YESYES # [ -S /etc/passwd ] && echo YES --無傳回值------------------------------------- -N file 測試檔案最後一次至今有無更改過 # [ -N /etc/passwd ] && echo YES --無傳回值 # useradd a# [ -N /etc/passwd ] && echo YESYES------------------------------------- file1 -nt file2 --file1是否比file2新 -n 比較哪個檔案新(和t在一起) True if file1 is newer (according to odification date) than file2, or if file1 exists and file2 does not.# [ /etc/passwd -nt /var/log/messages ] && echo YES # [ /var/log/messages -nt /etc/passwd ] && echo YESYES ------------------------------------- file1 -ot file2 --測試filt1是否老於file2 True if file1 is older than file2, or if file2 exists and file1 does not.# [ /var/log/messages -ot /etc/passwd ] && echo YESYES ------------------------------------- file1 -ef file2 True if file1 and file2 refer to the same device and inode numbers. # [ /etc/init.d -ef /etc/rc.d/init.d ] && echo YES --可以用於測試兩個檔案是否是永久連結的關係YES ------------------------------------- 字串運算式: -z string 字串true,如果字串是空的。# [ -z '' ] && echo YESYES # [ -z 'aa' ] && echo YES --無傳回值 ----------------- string -n string 字串true,如果字串不為空白。# [ -n 'aa' ] && echo YESYES # [ -n '' ] && echo YES --無傳回值----------------- string1 == string2 True if the strings are equal. = may be used in place of == for strict POSIX compliance.# [ 'aa' == 'aa' ] && echo YESYES # [ 'aa' == 'ab' ] && echo YES ----------------- string1 != string2 True if the strings are not equal.# [ 'aa' != 'ab' ] && echo YESYES # [ 'aa' != 'aa' ] && echo YES --無傳回值 ----------------- string1 < string2 True if string1 sorts before string2 lexicographically in the current locale.# [ aa \< aaa ] && echo YESYES # [ aaa \< ccc ] && echo YESYES string1 > string2 True if string1 sorts after string2 lexicographically in the current locale. 整數對比運算式:arg1 OP arg2-eq equal等於-ne not equal不等於-lt lesser than小於-le lesser equal小於等於-gt granter then大於-ge granter equal大於等於 # [ 1 -eq 1 ] && echo YESYES# [ 1 -eq 2 ] && echo YES # [ 1 -ne 2 ] && echo YESYES # [ 1 -lt 2 ] && echo YESYES # [ 2 -gt 1 ] && echo YESYES # [ 1 -le 1 ] && echo YESYES# [ 1 -le 2 ] && echo YESYES # [ 2 -ge 2 ] && echo YESYES# [ 3 -ge 2 ] && echo YESYES 運算式的邏輯組合:1、&& -a邏輯與2、|| -o邏輯或3、! 邏輯非 [ 1 -gt 2 ] -a [ -f /etc/passwd ][ 1 -gt 2 ] && [ -f /etc/passwd ] 或:[ 1 -gt 2 ] -o [ -f /etc/passwd ][ 1 -gt 2 ] || [ -f /etc/passwd ] 非:[ 1 -gt 2 ] -a [ ! -f /etc/passwd ] 總結:1、判斷檔案類型-f-O -u -L -h -nt -ot -k -s -Stest -f /etc/passwd[ -f /etc/passwd ] 2、字串-z -n==!=>=<= 3、整數-eq -gt -ge -lt -le 結構化語句:if for while until case function --------------------------------------------If 語句 --用於判斷一個點 if list; then list; [ elif list; then list; ] ... [ else list; ] fi The if list is executed. If its exit status is zero, the then list is executed. Otherwise, each elif list is executed in turn, and if its exit status is zero, the corresponding then list is executed and the command completes. Otherwise, the else list is executed, if present. The exit status is the exit sta- tus of the last command executed, or zero if no condition tested true. if單分支if [ ] ...thencommand01 ...fi雙分支 if [ ]thencommand01elsecommand01fi for --迴圈結構化語句(一般是給定區間或者範圍來取值)格式1:for name [ in word ] ; do list ; done 格式2:for (( expr1 ; expr2 ; expr3 )) ; do list ; done for i in 1 2 3 doecho $idone for i in {1..10}doecho $idone for ((i=1;i<=10;i++))doecho $idone while --當條件成立的時候迴圈while :doecho hellodone until --當條件不成立的時候迴圈until []doecho hellodone continue/break while --當條件成立時迴圈while [ 1 = 1 ]doecho "i love you forever"done # while : ; do echo 'i love you forever!!!'; sleep 3s ;done # while true ; do echo 'i love you forever!!!'; sleep 3s ;done while的另一種模式:# vim a.txt123abc456 while read linedoecho $linedone<a.txt cat a.txt | while read line;do echo $line; done until --當條件不成立的時候迴圈until [ 1 != 1 ]docommand1command2done break --做迴圈時如果滿足條件強制可以跳出迴圈,此時迴圈結束continue --滿足條件時也可以跳出迴圈,但可以迴圈下一個元素。 case --分支判斷語句(可以判斷一個面(區間)) case $1 incase1)command01;;case2)command02;;case3)command03.....*)esac 函數1、在編寫Shell指令碼程式時,將一些需要重複使用的命令操作,定義為公用使用的語句塊,即可稱為函數2、合理使用Shell函數,可以使指令碼內容更加簡潔,增強程式的易讀性,提高執行效率 function_name() {command1command2 } function_name --調用函數 function function_name() { } 顯示選擇菜單:select name in [ a b c ]do done --------------------------------------------漢字屬於字串 用字串的格式 #sh -n xxx.sh 檢查文法#sh -x xxx.sh 偵錯模式 ------------------------------------------- • bash shell 調試方法 • 開啟偵錯模式• $set -x• $bash -x shell.sh • 關閉偵錯模式• $set +x sh -n test.sh --檢查文法(結構化語句的文法)sh -x test.sh --調試 如果參數過太多,出現這個報錯:too many arguments,需要使用xargsxargs (1) - build and execute command lines from standard input # awk -F: '{print $1}' /etc/passwd | xargs -i mkdir -p {}