先說明以下內容來自: http://c.biancheng.net/cpp/shell/ ,C語言中文網,請大家支持原作,點擊鏈接查看。
我寫下來只是作為筆記,如果侵權,請留言,立馬刪除。
Shell是一種腳本語言,那么,就必須有解釋器來執行這些腳本,常見的腳本解釋器有:
bash:是Linux標准默認的shell。bash由Brian Fox和Chet Ramey共同完成,是BourneAgain Shell的縮寫,內部命令一共有40個。
sh: 由Steve Bourne開發,是Bourne Shell的縮寫,sh 是Unix 標准默認的shell。
另外還有:ash、 csh、 ksh等。
常見的編程語言分為兩類:一個是編譯型語言,如:c/c++/java等,它們遠行前全部一起要經過編譯器的編譯。另一個解釋型語言,執行時,需要使用解釋器一行一行地轉換為代碼,如:awk, perl, python與shell等。
Shell 經過了POSIX的標准化,所以它是可以在不同的linux系統上進行移植。
關於注釋的問題: 在shell中使用#進行注釋,注意,sh里面沒有多行注釋,只能每一行加一個#號;
第一個shell腳本程序:
#!/bin/bash # 上面中的 #! 是一種約定標記, 它可以告訴系統這個腳本需要什么樣的解釋器來執行; echo "Hello, world!"
變量:
定義變量:
country="China" Number=100注意: 1,變量名和等號之間不能有空格;
2,首個字符必須為字母(a-z,A-Z)。
3, 中間不能有空格,可以使用下划線(_)。
4, 不能使用標點符號。
5, 不能使用bash里的關鍵字(可用help命令查看保留關鍵字)。
使用變量:
只需要在一個定義過的變量前面加上美元符號 $ 就可以了, 另外,對於變量的{} 是可以選擇的, 它的目的為幫助解釋器識別變量的邊界.
country="China" echo $country echo ${country} echo "I love my ${country}abcd!"#這個需要有{}的;重定義變量: 直接把變量重新像開始定義的那樣子賦值就可以了:
country="China" country="ribenguizi"只讀變量: 用 readonly 命令 可以把變量字義為只讀變量。
readonly country="China" #或 country="China" readonly country刪除變量: 使用unset命令可以刪除變量,但是不能刪除只讀的變量。用法:
unset variable_name變量類型
運行shell時,會同時存在三種變量:1) 局部變量
局部變量在腳本或命令中定義,僅在當前shell實例中有效,其他shell啟動的程序不能訪問局部變量。2) 環境變量
所有的程序,包括shell啟動的程序,都能訪問環境變量,有些程序需要環境變量來保證其正常運行。必要的時候shell腳本也可以定義環境變量。3) shell變量
shell變量是由shell程序設置的特殊變量。shell變量中有一部分是環境變量,有一部分是局部變量,這些變量保證了shell的正常運行
特殊變量:
$* 和 $@ 的區別為: $* 和 $@ 都表示傳遞給函數或腳本的所有參數,不被雙引號(" ")包含時,都以"$1" "$2" … "$n" 的形式輸出所有參數。但是當它們被雙引號(" ")包含時,"$*" 會將所有的參數作為一個整體,以"$1 $2 … $n"的形式輸出所有參數;"$@" 會將各個參數分開,以"$1" "$2" … "$n" 的形式輸出所有參數。
$? 可以獲取上一個命令的退出狀態。所謂退出狀態,就是上一個命令執行后的返回結果。退出狀態是一個數字,一般情況下,大部分命令執行成功會返回 0,失敗返回 1。
Shell中的替換
轉義符:
在echo中可以用於的轉義符有:
使用 echo 命令的 –E 選項禁止轉義,默認也是不轉義的; 使用 –n 選項可以禁止插入換行符;
使用 echo 命令的 –e 選項可以對轉義字符進行替換。
另外,注意,經過我的實驗,得到:
echo "\\" #得到 \ echo -e "\\" #得到 \ echo "\\\\" #得到 \\ echo -e "\\" #得到 \命令替換:
它的意思就是說我們把一個命令的輸出賦值給一個變量,方法為把命令用反引號(在Esc下方)引起來. 比如:
directory=`pwd` echo $directory變量替換:
可以根據變量的狀態(是否為空、是否定義等)來改變它的值.
Shell運算符
算數運算符:
原生bash不支持簡單的數學運算,但是可以通過其他命令來實現,例如 awk 和 expr. 下面使用expr進行; expr是一款表達式計算工具,使用它可以完成表達式的求值操作;
比如:
a=10 b=20 expr $a + $b expr $a - $b expr $a \* $b expr $a / $b expr $a % $b a=$b注意: 1. 在expr中的乖號為:\*
2. 在 expr中的 表達式與運算符之間要有空格,否則錯誤;
3. 在[ $a == $b ]與[ $a != $b ]中,要需要在方括號與變量以及變量與運算符之間也需要有括號, 否則為錯誤的。(親測過)
關系運算符:
只支持數字,不支持字符串,除非字符串的值是數字。常見的有:
注意:也別忘記了空格;
布爾運算符:
字符串運算符:
文件測試運算符:
檢測 Unix 文件的各種屬性。
Shell中的字符串
單引號的限制:
- 單引號里的任何字符都會原樣輸出,單引號字符串中的變量是無效的;
- 單引號字串中不能出現單引號(對單引號使用轉義符后也不行)。
雙引號的優點:
- 雙引號里可以有變量
- 雙引號里可以出現轉義字符
拼接字符串:
country="China" echo "hello, $country" #也可以 echo "hello, "$country" "獲取字符串長度:
string="abcd" echo ${#string} #輸出 4提取子字符串:
string="alibaba is a great company" echo ${string:1:4} #輸出liba查找子字符串:
string="alibaba is a great company" echo `expr index "$string" is`
處理路經的字符串:
例如:當一個路徑為 /home/xiaoming/1.txt時,如何怎么它的路徑(不帶文件) 和如何得到它的文件名??
得到文件名使用 bashname命令:
# 參數: # -a,表示處理多個路徑; # -s, 用於去掉指定的文件的后綴名; basename /home/yin/1.txt -> 1.txt basename -a /home/yin/1.txt /home/zhai/2.sh -> 1.txt 2.sh basename -s .txt /home/yin/1.txt -> 1 basename /home/yin/1.txt .txt -> 1得到路徑名(不帶文件名)使用 dirname命令:
參數:沒有啥參數; //例子: dirname /usr/bin/ -> /usr dirname dir1/str dir2/str ->dir1
dir2
dirname stdio.h -> .
Shell的數組:
bash支持一維數組, 不支持多維數組, 它的下標從0開始編號. 用下標[n] 獲取數組元素;
定義數組:
在shell中用括號表示數組,元素用空格分開。 如:
array_name=(value0 value1 value2 value3)也可以單獨定義數組的各個分量,可以不使用連續的下標,而且下標的范圍沒有限制。如:
array_name[0]=value0 array_name[1]=value1 array_name[2]=value2讀取數組:
讀取某個下標的元素一般格式為:
${array_name[index]}讀取數組的全部元素,用@或*
${array_name[*]} ${array_name[@]}
獲取數組的信息:
取得數組元素的個數:
length=${#array_name[@]} #或 length=${#array_name[*]}
獲取數組的下標:
length=${!array_name[@]} #或 length=${!array_name[*]}
取得數組單個元素的長度:
lengthn=${#array_name[n]}
printf函數:
它與c語言中的printf相似,不過也有不同,下面列出它的不同的地方:
- printf 命令不用加括號
- format-string 可以沒有引號,但最好加上,單引號雙引號均可。
- 參數多於格式控制符(%)時,format-string 可以重用,可以將所有參數都轉換。
- arguments 使用空格分隔,不用逗號。
下面為例子:
# format-string為雙引號 $ printf "%d %s\n" 1 "abc" 1 abc # 單引號與雙引號效果一樣 $ printf '%d %s\n' 1 "abc" 1 abc # 沒有引號也可以輸出 $ printf %s abcdef abcdef # 格式只指定了一個參數,但多出的參數仍然會按照該格式輸出,format-string 被重用 $ printf %s abc def abcdef $ printf "%s\n" abc def abc def $ printf "%s %s %s\n" a b c d e f g h i j a b c d e f g h i j # 如果沒有 arguments,那么 %s 用NULL代替,%d 用 0 代替 $ printf "%s and %d \n" and 0 # 如果以 %d 的格式來顯示字符串,那么會有警告,提示無效的數字,此時默認置為 0 $ printf "The first program always prints'%s,%d\n'" Hello Shell -bash: printf: Shell: invalid number The first program always prints 'Hello,0' $
Shell中條件語句
if 語句
包括:1, if [ 表達式 ] then 語句 fi
2. if [ 表達式 ] then 語句 else 語句 fi
3. if [ 表達式] then 語句 elif[ 表達式 ] then 語句 elif[ 表達式 ] then 語句 …… fi
例子:
a=10 b=20 if [ $a == $b ] then echo "a is equal to b" else echo "a is not equal to b" fi另外:if ... else 語句也可以寫成一行,以命令的方式來運行,像這樣:
if test $[2*3] -eq $[1+5]; then echo 'The two numbers are equal!'; fi;其中,test 命令用於檢查某個條件是否成立,與方括號([ ])類似。
case …… esac語句
case ... esac 與其他語言中的 switch ... case 語句類似,是一種多分枝選擇結構。case語句格式如下:
case 值 in 模式1) command1 command2 command3 ;; 模式2) command1 command2 command3 ;; *) command1 command2 command3 ;; esac其中, 1. 取值后面必須為關鍵字 in,每一模式必須以右括號結束。取值可以為變量或常數。匹配發現取值符合某一模式后,其間所有命令開始執行直至 ;;。;; 與其他語言中的 break 類似,意思是跳到整個 case 語句的最后。2. 如果無一匹配模式,使用星號 * 捕獲該值,再執行后面的命令。
Shell 的循環語句
for 循環
一般格式為:
for 變量 in 列表 do command1 command2 ... commandN done注意:列表是一組值(數字、字符串等)組成的序列,每個值通過空格分隔。每循環一次,就將列表中的下一個值賦給變量。 例如:
順序輸出當前列表的數字:
for loop in 1 2 3 4 5 do echo "The value is: $loop" done顯示主目錄下以 .bash 開頭的文件:
#!/bin/bash for FILE in $HOME/.bash* do echo $FILE donewhile循環
一般格式為:
while command do Statement(s) to be executed if command is true done例如:
COUNTER=0 while [ $COUNTER -lt 5 ] do COUNTER='expr $COUNTER+1' echo $COUNTER doneuntil 循環
until 循環執行一系列命令直至條件為 true 時停止。until 循環與 while 循環在處理方式上剛好相反。 常用格式為:
until command do Statement(s) to be executed until command is true donecommand 一般為條件表達式,如果返回值為 false,則繼續執行循環體內的語句,否則跳出循環。
類似地, 在循環中使用 break 與continue 跳出循環。 另外,break 命令后面還可以跟一個整數,表示跳出第幾層循環。
Shell函數
Shell函數必須先定義后使用,定義如下,
function_name () { list of commands [ return value ] }
也可以加上function關鍵字:
function function_name () { list of commands [ return value ] }注意:1. 調用函數只需要給出函數名,不需要加括號。
2. 函數返回值,可以顯式增加return語句;如果不加,會將最后一條命令運行結果作為返回值。
3. Shell 函數返回值只能是整數,一般用來表示函數執行成功與否,0表示成功,其他值表示失敗。
4. 函數的參數可以通過 $n 得到.如:
5. 像刪除變量一樣,刪除函數也可以使用 unset 命令,不過要加上 .f 選項,如下所示:funWithParam(){ echo "The value of the first parameter is $1 !" echo "The value of the second parameter is $2 !" echo "The value of the tenth parameter is ${10} !" echo "The value of the eleventh parameter is ${11} !" echo "The amount of the parameters is $# !" # 參數個數 echo "The string of the parameters is $* !" # 傳遞給函數的所有參數 } funWithParam 1 2 3 4 5 6 7 8 9 34 73unset .f function_name
shell的文件包含:
Shell 也可以包含外部腳本,將外部腳本的內容合並到當前腳本。使用:
. filename #或 source filename
1. 兩種方式的效果相同,簡單起見,一般使用點號(.),但是注意點號(.)和文件名中間有一空格。
2. 被包含腳本不需要有執行權限。