1、shell中的變量定義和引用
(1)變量定義和初始化。shell是弱類型語言(語言中的變量如果有明確的類型則屬於強類型語言;變量沒有明確類型就是弱類型語言),和C語言不同。在shell編程中定義變量不需要制定類型,也沒有類型這個概念。
(2)變量定義時可以初始化,使用=進行初始化賦值。在shell中賦值的=兩邊是不能有空格的。
注意:shell對語法非常在意,非常嚴格。很多地方空格都是必須沒有或者必須有,而且不能隨意有沒有空格。
(3)變量賦值,變量定義后可以再次賦值,新的賦值會覆蓋老的賦值。shell中並不刻意區分變量的定義和賦值,反正每個變量就是一個符號,這個符號的值就是最后一個給他賦值時的值。
(4)變量引用。shell中引用一個變量必須使用$符號,$符號就是變量解引用符號。
注意:$符號后面跟一個字符串,這個字符串就會被當作變量去解析。如果這個字符串本身沒有定義,執行時並不會報錯,而是把這個變量解析為空。也就是說在shell中沒有被定義的變量其實就相當於是一個定義並賦值為空的變量。
注意:變量引用的時候可以$var,也可以${var}。這兩種的區別是在某些情況下只能用${var}而不能簡單的$var
2、shell中無引用、單引號和雙引號的區別
(1)shell中使用字符串可以不加雙引號,直接使用。而且有空格時也可以,但是缺陷是不能輸出"或者其他轉義字符。
(2)shell中也可以使用單引號來表示字符串,也是直接使用的,不能輸出轉義字符。
(3)單引號中:完全字面替換(不可包含單引號本身)
(4)雙引號中:
$加變量名可以取變量的值
反引號仍表示命令替換
\$表示$的字面值 輸出$符號
\`表示`的字面值
\"表示"的字面值
\\表示\的字面值
除以上情況之外,在其它字符前面的\無特殊含義,只表示字面值。
#!/bin/sh #var string="hello world" echo $string echo "a\"bc" echo 'a\"bc' echo $c
3、shell中調用linux命令
(1)直接執行
(2)反引號括起來執行。有時候我們在shell中調用linux命令是為了得到這個命令的返回值(結果值),這時候就適合用一對反引號(鍵盤上ESC按鍵下面的那個按鍵,和~在一個按鍵上)來調用執行命令。
PWD=`pwd` echo $PWD MYPATH="`pwd`\include" MYPATH1='`pwd`\include' echo "MYPATH=$MYPATH" echo "MYPATH1=$MYPATH1"
4、shell中的選擇分支結構
(1)shell的if語言用法很多,在此只介紹常用的,其他感興趣可以自己去學
(2)典型if語言格式
if [表達式]; then
xxx
else
xxx
fi
(3)if的典型應用
判斷文件是否存在。(-f),注意[]里面前后都有空格,不能省略。
判斷目錄是否存在 (-d)
判斷字符串是否相等("str1" = "str2"),注意用一個等號而不是兩個
判斷數字是否相等(-eq)、大於(-gt)、小於(-lt)、大於等於(-ge)、小於等於(-le) 回憶一下在ARM裸機中講述ARM匯編條件執行時,曾經用過這些條件判斷的縮寫。(eq就是equal,gt就是greater than,lt就是less than,ge就是greater or equal,le就是less or equal)
判斷字符串是否為空(-z)注意-z判斷時如果變量本身沒定義也是不成立(也就是說-z認為沒定義不等於為空)
(4)if判斷式中使用“-o”表示邏輯或
相當於C語言中在if后面的條件式中用邏輯與、邏輯或來連接2個式子,最終的if中是否成立取決於2個式子的邏輯運算結果。
(5)邏輯與&&和邏輯或||與簡寫的if表達式相結合
#!/bin/sh # comment #簡寫if [ "awbc" = "abc" ] || echo "ok1" [ "abc" = "abc" ] && echo "ok2" #-z判斷字符串是否空 str="" if [ -z $str ]; then echo "yes" else echo "no" fi # -eq -gt -lt -ge -le if [ 21 -gt 2 ]; then echo "yes" else echo "no" fi #判斷字符串 str="aaboot" if [ $str = "aboot" ]; then echo "yes" else echo "no" fi #-o 表示邏輯或 if [ 1234 -eq 123 -o "abc4" = "abc" ]; then echo "yes" else echo "no" fi #判斷文件是否存在 #if [ -f ./dir/a.txt ]; then # echo "yes" #else #test2 當前目錄下 在創建dir並創建a.txt # mkdir dir # cd dir # touch a.txt # cd .. #fi
5、for循環
(1)要求:能看懂、能改即可。不要求能夠完全不參考寫出來。因為畢竟嵌入式並不需要完全重新手寫shell,系統管理員(服務器運維人員,應用層系統級管理開發的才需要完全掌握shell)
6、while循環
(1)和C語言的循環在邏輯上無差別
(2)要注意很多格式要求,譬如:while后面的[]兩邊都有空格,[]后面有分號分號(如果do放在一行的話),i++的寫法中有兩層括號。
#!/bin/sh # 循環 #while i=1 j=11 #echo $(($i + $j)) while [ $i -le $j ]; do echo $i i=$(($i+1)) done #for #for i in 1 2 3 4 5 #for i in `ls` #do # echo $i #done
7、echo的創建和追加輸入文件
(1)在shell中可以直接使用echo指令新建一個文件,並且將一些內容傳入這個文件中。創建文件並輸入內容的關鍵就是>。
(2)還可以使用echo指令配合追加符號>> 向一個已經存在的文件末尾追加輸入內容。
#!/bin/sh #echo 創建文件並追加文件 echo "#include<stdio> int main() { int b; return 0; }">a.c #追加 echo "追加內容">>a.c
8、case語句
(1)shell中的case語句和C語言中的switch case語句作用一樣,格式有差異
(2)shell中的case語句天生沒有break,也不需要break,和C語言中的switch case不同。shell中的case默認就是匹配上哪個執行哪個,不會說執行完了還去執行后面的其他case(就好像shell中的case語言默認都帶了break)。
9、調用shell程序的傳參
(1)C語言中可以通過main函數的argc和argv給程序傳參(詳情參考《4.8.3.argc、argv與main函數的傳參》)
(2)shell程序本身也可以在調用時傳參給他。在shell程序內部使用傳參也是使用的一些特定符號來表示的,包括:
$#表示調用該shell時傳參的個數。($#計數時只考慮真正的參數個數)
$0、$1、$2·····則依次表示傳參的各個參數。
C語言:./a.out aa bb cc argc = 4, argv[0] = ./a.out, argv[1]是第一個有效參數····
shell:source a.sh aa bb cc $# = 3, $0是執行這個shell程序的解析程序的名字,$1是第一個有效參數的值,$2是第2個有效參數的值·····
注意:shell中的很多語法特性和C語言中是相同的,也有很多是不同的。所以大家學的越多越容易混淆(本質原因還是用的不熟悉,用的少),解決方案是:做筆記、作總結、多寫代碼經常用
#!/bin/sh #shell 傳參 ./case.sh aa bb cc 輸出 3 aa bb cc echo $# $0 $1 $2 $3 #case #var=2 #case $var in #1) echo "1" ;; #2) echo "2" ;; #esac
10、while循環和case語言和傳參結合
(1)shell中的break關鍵字和C語言中意義相同(都是跳出)但是用法不同。因為shell中case語句默認不用break的,因此在shell中break只用於循環跳出。所以當while中內嵌case語句時,case中的break是跳出外層的while循環的,不是用來跳出case語句的。
(2)shell中的$# $1等內置變量的值不是不可變的,而是可以被改變,被shift指令改變。shift指令有點像左移運算符,把我們給shell程序的傳參左移了一個移出去了,原來的$2變成了新的$1,原來的$#少了1個。