linux下的shell腳本(基本)
先說明以下內(nèi)容來自: http://c.biancheng.net/cpp/shell/ ,C語言中文網(wǎng)填帽,請大家支持原作蛛淋,點擊鏈接查看。
我寫下來只是作為筆記篡腌,如果侵權褐荷,請留言,立馬刪除嘹悼。
Shell是一種腳本語言叛甫,那么,就必須有解釋器來執(zhí)行這些腳本杨伙,常見的腳本解釋器有:
bash:是Linux標準默認的shell其监。bash由Brian Fox和Chet Ramey共同完成,是BourneAgain Shell的縮寫限匣,內(nèi)部命令一共有40個抖苦。
sh: 由Steve Bourne開發(fā),是Bourne Shell的縮寫米死,sh 是Unix 標準默認的shell锌历。
另外還有:ash、 csh哲身、 ksh等辩涝。
常見的編程語言分為兩類:一個是編譯型語言,如:c/c++/java等勘天,它們遠行前全部一起要經(jīng)過編譯器的編譯怔揩。另一個解釋型語言,執(zhí)行時脯丝,需要使用解釋器一行一行地轉(zhuǎn)換為代碼商膊,如:awk, perl, python與shell等。
Shell 經(jīng)過了POSIX的標準化宠进,所以它是可以在不同的linux系統(tǒng)上進行移植晕拆。
關于注釋的問題: 在shell中使用#進行注釋,注意,sh里面沒有多行注釋实幕,只能每一行加一個#號吝镣;
第一個shell腳本程序:
#!/bin/bash
# 上面中的 #! 是一種約定標記, 它可以告訴系統(tǒng)這個腳本需要什么樣的解釋器來執(zhí)行; 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) 環(huán)境變量
所有的程序抄谐,包括shell啟動的程序,都能訪問環(huán)境變量扰法,有些程序需要環(huán)境變量來保證其正常運行。必要的時候shell腳本也可以定義環(huán)境變量毅厚。
3) shell變量
shell變量是由shell程序設置的特殊變量塞颁。shell變量中有一部分是環(huán)境變量,有一部分是局部變量吸耿,這些變量保證了shell的正常運行
特殊變量:
@ 的區(qū)別為: @ 都表示傳遞給函數(shù)或腳本的所有參數(shù)祠锣,不被雙引號(" ")包含時,都以"2" … "*" 會將所有的參數(shù)作為一個整體,以"2 … @" 會將各個參數(shù)分開澡腾,以"2" … "$n" 的形式輸出所有參數(shù)。
$? 可以獲取上一個命令的退出狀態(tài)糕珊。所謂退出狀態(tài)动分,就是上一個命令執(zhí)行后的返回結(jié)果。退出狀態(tài)是一個數(shù)字红选,一般情況下澜公,大部分命令執(zhí)行成功會返回 0,失敗返回 1喇肋。
Shell中的替換
轉(zhuǎn)義符:
在echo中可以用于的轉(zhuǎn)義符有:
使用 echo 命令的 –E 選項禁止轉(zhuǎn)義坟乾,默認也是不轉(zhuǎn)義的迹辐; 使用 –n 選項可以禁止插入換行符嫩与;
使用 echo 命令的 –e 選項可以對轉(zhuǎn)義字符進行替換跋破。
另外柒爵,注意贷痪,經(jīng)過我的實驗鲤孵,得到:
echo "\\" #得到 \ echo -e "\\" #得到 \ echo "\\\\" #得到 \\ echo -e "\\" #得到 \
命令替換:
它的意思就是說我們把一個命令的輸出賦值給一個變量,方法為把命令用反引號(在Esc下方)引起來. 比如:
directory=`pwd` echo $directory
變量替換:
可以根據(jù)變量的狀態(tài)(是否為空歹叮、是否定義等)來改變它的值.
Shell運算符
算數(shù)運算符:
原生bash不支持簡單的數(shù)學運算寓涨,但是可以通過其他命令來實現(xiàn)澎蛛,例如 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 ]中,要需要在方括號與變量以及變量與運算符之間也需要有括號主到, 否則為錯誤的茶行。(親測過)
關系運算符:
只支持數(shù)字,不支持字符串登钥,除非字符串的值是數(shù)字畔师。常見的有:
注意:也別忘記了空格;
布爾運算符:
字符串運算符:
文件測試運算符:
檢測 Unix 文件的各種屬性牧牢。
Shell中的字符串
單引號的限制:
- 單引號里的任何字符都會原樣輸出看锉,單引號字符串中的變量是無效的;
- 單引號字串中不能出現(xiàn)單引號(對單引號使用轉(zhuǎn)義符后也不行)塔鳍。
雙引號的優(yōu)點:
- 雙引號里可以有變量
- 雙引號里可以出現(xiàn)轉(zhuǎn)義字符
拼接字符串:
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`
處理路經(jīng)的字符串:
例如:當一個路徑為 /home/xiaoming/1.txt時伯铣,如何怎么它的路徑(不帶文件) 和如何得到它的文件名?轮纫?
得到文件名使用 bashname命令:
<pre># 參數(shù):
-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命令:
參數(shù):沒有啥參數(shù)掌唾; //例子:
dirname /usr/bin/ -> /usr dirname dir1/str dir2/str ->
dir1
dir2
dirname stdio.h -> .
Shell的數(shù)組:
bash支持一維數(shù)組, 不支持多維數(shù)組, 它的下標從0開始編號. 用下標[n] 獲取數(shù)組元素放前;
定義數(shù)組:
在shell中用括號表示數(shù)組,元素用空格分開郑兴。 如:
array_name=(value0 value1 value2 value3)
也可以單獨定義數(shù)組的各個分量犀斋,可以不使用連續(xù)的下標,而且下標的范圍沒有限制情连。如:
array_name[0]=value0
array_name[1]=value1
array_name[2]=value2</pre>
讀取數(shù)組:
讀取某個下標的元素一般格式為:
${array_name[index]}
讀取數(shù)組的全部元素叽粹,用@或*
${array_name[*]}
${array_name[@]}
獲取數(shù)組的信息:
取得數(shù)組元素的個數(shù):
length=${#array_name[@]}
#或
length=${#array_name[*]}
獲取數(shù)組的下標:
length=${!array_name[@]}
#或
length=${!array_name[*]}
取得數(shù)組單個元素的長度:
lengthn=${#array_name[n]}
printf函數(shù):
它與c語言中的printf相似,不過也有不同,下面列出它的不同的地方:
- printf 命令不用加括號
- format-string 可以沒有引號虫几,但最好加上锤灿,單引號雙引號均可。
- 參數(shù)多于格式控制符(%)時辆脸,format-string 可以重用但校,可以將所有參數(shù)都轉(zhuǎn)換。
- arguments 使用空格分隔啡氢,不用逗號状囱。
下面為例子:
<pre># format-string為雙引號
$ printf "%d %s\n" 1 "abc"
1 abc單引號與雙引號效果一樣
printf '%d %s\n' 1 "abc"
1 abc沒有引號也可以輸出
printf %s abcdef
abcdef格式只指定了一個參數(shù),但多出的參數(shù)仍然會按照該格式輸出倘是,format-string 被重用
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 "The first program always prints'%s,%d\n'" Hello Shell -bash: printf: Shell: invalid number
The first program always prints 'Hello,0' $</pre>
Shell中條件語句
if 語句
包括:1瘤睹, if [ 表達式 ] then 語句 fi
2. if [ 表達式 ] then 語句 else 語句 fi
- if [ 表達式] then 語句 elif[ 表達式 ] then 語句 elif[ 表達式 ] then 語句 …… fi
例子:
[](javascript:void(0); "復制代碼")
<pre>a=10 b=20
if [ b ] then
echo "a is equal to b"
else
echo "a is not equal to b"
fi</pre>
另外:if ... else 語句也可以寫成一行升敲,以命令的方式來運行,像這樣:
<pre>if test [1+5]; then echo 'The two numbers are equal!'; fi;</pre>
其中轰传,test 命令用于檢查某個條件是否成立驴党,與方括號([ ])類似。
case …… esac語句
case ... esac 與其他語言中的 switch ... case 語句類似获茬,是一種多分枝選擇結(jié)構鼻弧。case語句格式如下:
<pre>case 值 in 模式1)
command1
command2
command3
;;
模式2)
command1
command2
command3
;; *)
command1
command2
command3
;; esac</pre>
其中, 1. 取值后面必須為關鍵字 in锦茁,每一模式必須以右括號結(jié)束。取值可以為變量或常數(shù)叉存。匹配發(fā)現(xiàn)取值符合某一模式后码俩,其間所有命令開始執(zhí)行直至 ;;。;; 與其他語言中的 break 類似歼捏,意思是跳到整個 case 語句的最后稿存。2. 如果無一匹配模式,使用星號 * 捕獲該值瞳秽,再執(zhí)行后面的命令瓣履。
Shell 的循環(huán)語句
**for 循環(huán) **
一般格式為:
<pre>for 變量 in 列表 do command1
command2
...
commandN done</pre>
注意:列表是一組值(數(shù)字、字符串等)組成的序列练俐,每個值通過空格分隔袖迎。每循環(huán)一次,就將列表中的下一個值賦給變量。 例如:
順序輸出當前列表的數(shù)字:
<pre>for loop in 1 2 3 4 5
do
echo "The value is: $loop"
done</pre>顯示主目錄下以 .bash 開頭的文件:
<pre>#!/bin/bash for FILE in FILE done</pre>
while循環(huán)
一般格式為:
<pre>while command do Statement(s) to be executed if command is true
done</pre>例如:
<pre>COUNTER=0
[
while [ COUNTER+1'
echo $COUNTER done</pre>](javascript:void(0); "復制代碼")
until 循環(huán)
until 循環(huán)執(zhí)行一系列命令直至條件為 true 時停止燕锥。until 循環(huán)與 while 循環(huán)在處理方式上剛好相反辜贵。 常用格式為:
<pre>until command do Statement(s) to be executed until command is true
done</pre>command 一般為條件表達式,如果返回值為 false归形,則繼續(xù)執(zhí)行循環(huán)體內(nèi)的語句托慨,否則跳出循環(huán)。
類似地暇榴, 在循環(huán)中使用 break 與continue 跳出循環(huán)厚棵。 另外,break 命令后面還可以跟一個整數(shù)蔼紧,表示跳出第幾層循環(huán)婆硬。
Shell函數(shù)
Shell函數(shù)必須先定義后使用,定義如下歉井,
<pre>function_name () {
list of commands
[ return value ]
}</pre>也可以加上function關鍵字:
<pre>function function_name () {
list of commands
[ return value ]
}</pre>注意:1. 調(diào)用函數(shù)只需要給出函數(shù)名柿祈,不需要加括號。
2. 函數(shù)返回值哩至,可以顯式增加return語句躏嚎;如果不加,會將最后一條命令運行結(jié)果作為返回值菩貌。
3. Shell 函數(shù)返回值只能是整數(shù)卢佣,一般用來表示函數(shù)執(zhí)行成功與否,0表示成功箭阶,其他值表示失敗虚茶。
4. 函數(shù)的參數(shù)可以通過 $n 得到.如:
<pre>funWithParam(){ echo "The value of the first parameter is 2 !"
echo "The value of the tenth parameter is {11} !"
echo "The amount of the parameters is * !" # 傳遞給函數(shù)的所有參數(shù)
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73</pre>
5. 像刪除變量一樣,刪除函數(shù)也可以使用 unset 命令仇参,不過要加上 .f 選項嘹叫,如下所示:
<pre>unset .f function_name</pre>
shell的文件包含:
Shell 也可以包含外部腳本,將外部腳本的內(nèi)容合并到當前腳本诈乒。使用:
<pre>. filename
或
source filename</pre>
1. 兩種方式的效果相同罩扇,簡單起見,一般使用點號(.)怕磨,但是注意點號(.)和文件名中間有一空格喂饥。
2. 被包含腳本不需要有執(zhí)行權限。