[TOC]
1.介紹
Shell是一個用C語言編寫的程序焕参,它是用戶使用Linux的橋梁理疙。Shell既是一種命令語言霞势,又是一種程序設(shè)計語言烹植。
在linux下,我們常用的是bash愕贡。
2.快速入門
新建helloworld.sh
touch helloworld.sh
編輯shell文件
#!/bin/bash
echo "helloworld"
-
#!
是一個約定的標(biāo)記草雕,它告訴系統(tǒng)這個腳本需要什么解釋器來執(zhí)行,即使用哪一種shell固以,這里指定bash墩虹。 - echo是shell的一個內(nèi)部指令,用于在屏幕上打印出指定的字符串憨琳。
腳本執(zhí)行
1../
的執(zhí)行
需要添加權(quán)限
chmod u+x helloworld.sh
執(zhí)行
./helloworld.sh
2.sh或者bash執(zhí)行
直接sh和bash執(zhí)行
3.變量
shell中所有類型都是字符串诫钓,所以不需要標(biāo)注類型。
- 語法格式:變量名=變量值
shell的語法要求
- 變量名和等號之間不能有空格
- 變量名首個字符必須為英文字母
- 不能包含標(biāo)點符號但能夠使用下劃線(_)
- 不能使用空格
- 不能使用bash里的關(guān)鍵字
shell的變量類型
類型 | 解釋 |
---|---|
局部變量 | 局部變量在腳本或命令中定義栽渴,僅在當(dāng)前 shell 實例中有效,其他 shell 啟動的程序不能訪問局部變量 |
環(huán)境變量 | 所有的程序稳懒,包括 shell 啟動的程序闲擦,都能訪問環(huán)境變量,有些程 序需要環(huán)境變量來保證其正常運(yùn)行场梆∈洌可以用過 set 命令查看當(dāng)前環(huán)境變量 |
shell 變量 | 由 shell 程序設(shè)置的特殊變量。shell 變量中有一部分是環(huán)境變量或油,有一部分是局部變量寞忿,這些變量保證了 shell 的正常運(yùn)行 |
變量的使用
1.定義變量
name="zhangsan"
2.引用變量
name="zhangsan"
echo ${name}
echo $name
引用一個定義過的變量,只要在變量名前面加 $ 即可顶岸,變量名外面的花括號是可選的腔彰,加不加都行叫编,加花括號是為了幫助解釋器識別變量的邊界。
3.重新定義變量
name="zhangsan"
echo ${name}
name="lisi"
echo ${name}
4. 只讀變量
name="zhangsan"
readonly name
name="lisi"
使用 readonly 命令可以將變量定義為只讀變量霹抛,只讀變量的值不能被改變搓逾。
5. 刪除變量
name="zhangsan"
unset name
echo $name
使用 unset 命令可以刪除變量,變量被刪除后不能再次使用杯拐,同時 unset 命令不能刪除只讀變量霞篡。
4.參數(shù)傳遞
在執(zhí)行 Shell 腳本時,可以向腳本傳遞參數(shù)端逼。腳本內(nèi)獲取參數(shù)的格式為:$n
朗兵。n 代表一個數(shù)字,1 為執(zhí)行腳本的第一個參數(shù)顶滩,2 為執(zhí)行腳本的第二個參數(shù)余掖,以此類推…
$0
表示當(dāng)前腳本名稱。
- 修改 helloworld.sh 為
#!/bin/bash
echo $1
echo $2
echo $3
- 執(zhí)行攜帶參數(shù)
./helloworld.sh haha wowow nini
haha
wowow
nini
5.shell字符串
shell 字符串可以用單引號诲祸,也可以用雙引號浊吏,也可以不用引號
單引號
name='my name is zhangsan'
- 單引號字符串中不支持引用變量,任何字符都會原樣輸出
- 單引號字串中不能出現(xiàn)單引號(對單引號使用轉(zhuǎn)義符后也不行)
雙引號
name='my name is zhangsan'
name_again="${name}"
- 雙引號里可以引有變量
- 雙引號里支持轉(zhuǎn)義字符
字符串長度
name='my name is zaomianbao'
echo ${#name} //執(zhí)行輸出為21
截取字符串
name='my name is zaomianbao'
echo ${name:11:20} //執(zhí)行輸出zaomianbao
6.shell數(shù)組
- bash 支持一維數(shù)組(不支持多維數(shù)組)救氯,并且沒有限定數(shù)組的大小找田。在 Shell 中,用括號來表示數(shù)組着憨,數(shù)組元素用 “空格” 符號分割開墩衙。定義數(shù)組的一般形式為:
array_name=(value1 … valuen)
下面的例子將展示 shell 數(shù)組常見的所有操作
[root@centos6-1 ~]# usernames=(1 2 33 44 adsd1)
//默認(rèn)讀取第一個
[root@centos6-1 ~]# echo ${usernames}
//讀取下標(biāo)為0的
[root@centos6-1 ~]# echo ${usernames[0]}
//讀取下標(biāo)為1的
[root@centos6-1 ~]# echo ${usernames[1]}
//讀取所有
[root@centos6-1 ~]# echo ${usernames[*]}
1 2 33 44 adsd1
//同樣是讀取所有
[root@centos6-1 ~]# echo ${usernames[@]}
1 2 33 44 adsd1
//獲取數(shù)組長度
[root@centos6-1 ~]# echo ${#usernames[@]}
//同樣可以獲取數(shù)組長度
[root@centos6-1 ~]# echo ${#usernames[*]}
7.特殊字符
字符 | 意義 |
---|---|
$# | 傳遞到腳本的參數(shù)個數(shù) |
$* | 以一個單字符串顯示所有向腳本傳遞的參數(shù) |
$$ | 腳本運(yùn)行的當(dāng)前進(jìn)程 ID 號 |
$! | 后臺運(yùn)行的最后一個進(jìn)程的 ID 號 |
$@ | 與 $* 相同,但是使用時加引號甲抖,并在引號中返回每個參數(shù) |
$? | 顯示最后命令的退出狀態(tài)漆改。0 表示沒有錯誤,其他任何值表明有錯誤 |
@區(qū)別:
- 相同點:都表示傳遞給腳本的所有參數(shù)准谚。
- 不同點:不被
" "
包含時挫剑,$ *
和$@
都以$1
?$2
…$n
的形式組成參數(shù)列表。被" “
包含時柱衔,"$*
"會將所有的參數(shù)作為一個整體樊破,以"$1 $2 … $n
" 的形式組成一個整串;"$@
" 會將各個參數(shù)分開,以 "$1
" “$2
” … “$n
” 的 形式組成一個參數(shù)列表唆铐。
8.算術(shù)運(yùn)算符
- Shell 和其他編程語音一樣哲戚,支持包括: 算術(shù)、關(guān)系艾岂、布爾顺少、字符串等運(yùn)算符。
- 原生 bash 不支持簡單的數(shù)學(xué)運(yùn)算,但是可以通過其他命令來實現(xiàn)脆炎,例如 awk 和 expr梅猿,expr 最常用。expr 是一款表達(dá)式計算工具腕窥,使用它能完成表達(dá)式的求值操作粒没。
1. 算術(shù)運(yùn)算符
運(yùn)算符 | 意義 |
---|---|
+ | 加法 |
- | 減法 |
* | 乘法 |
/ | 除法 |
% | 模,即取余 |
下面是詳細(xì)例子
#!/bin/bash
a=10
b=20
val=`expr $a + $b`
echo "a + b : $val"
val=`expr $a - $b`
echo "a - b : $val"
val=`expr $a \* $b`
echo "a * b : $val"
val=`expr $b / $a`
echo "b / a : $val"
val=`expr $b % $a`
echo "b % a : $val"
if [ $a == $b ]
then
echo "a 等于 b"
fi
if [ $a != $b ]
then
echo "a 不等于 b"
fi
執(zhí)行
[root@centos6-1 ~]# ./helloworld.sh
a + b : 30
a - b : -10
a * b : 200
b / a : 2
b % a : 0
a 不等于 b
注意:
- 1.乘號(*)前邊必須加反斜杠(\)
- 2.條件表達(dá)式要放在方括號之間簇爆,并且要有空格
2. 關(guān)系運(yùn)算符
關(guān)系運(yùn)算符只支持?jǐn)?shù)字癞松,不支持字符串,除非字符串的值是數(shù)字
運(yùn)算符 | 意義 |
---|---|
-eq | EQUAL 等于 |
-ne | NOT EQUAL 不等于 |
-gt | GREATER THAN 大于 |
-lt | LESS THAN 小于 |
-ge | GREATER THAN OR EQUAL 大于等于 |
-le | LESS THAN OR EQUAL 小于等 |
下面是詳細(xì)例子
#!/bin/bash
a=10
b=20
if [ $a -eq $b ]
then
echo "$a -eq $b : a 等于 b"
else
echo "$a -eq $b: a 不等于 b"
fi
if [ $a -ne $b ]
then
echo "$a -ne $b: a 不等于 b"
else
echo "$a -ne $b : a 等于 b"
fi
if [ $a -gt $b ]
then
echo "$a -gt $b: a 大于 b"
else
echo "$a -gt $b: a 不大于 b"
fi
if [ $a -lt $b ]
then
echo "$a -lt $b: a 小于 b"
else
echo "$a -lt $b: a 不小于 b"
fi
if [ $a -ge $b ]
then
echo "$a -ge $b: a 大于或等于 b"
else
echo "$a -ge $b: a 小于 b"
fi
if [ $a -le $b ]
then
echo "$a -le $b: a 小于或等于 b"
else
echo "$a -le $b: a 大于 b"
fi
執(zhí)行
[root@centos6-1 ~]# ./helloworld.sh
10 -eq 20: a 不等于 b
10 -ne 20: a 不等于 b
10 -gt 20: a 不大于 b
10 -lt 20: a 小于 b
10 -ge 20: a 小于 b
10 -le 20: a 小于或等于 b
[root@centos6-1 ~]#
3. 布爾運(yùn)算符
運(yùn)算符 | 意義 |
---|---|
&& | 與 |
|| | 或 |
下面是詳細(xì)例子
#!/bin/bash
a=10
b=20
if [[ $a -lt 100 && $b -gt 100 ]]
then
echo "返回 true"
else
echo "返回 false"
fi
if [[ $a -lt 100 || $b -gt 100 ]]
then
echo "返回 true"
else
echo "返回 false"
fi
執(zhí)行
[root@centos6-1 ~]# ./helloworld.sh
返回 false
返回 true
4. 字符串運(yùn)算符
操作符 | 意義 |
---|---|
-z | 字符串長度是否為 0入蛆,為 0 返回 true |
-n | 字符串長度是否為 0响蓉,不為 0 返回 true |
str | 字符串是否為空,不為空返回 true |
下面是詳細(xì)例子
#!/bin/bash
a="abc"
b="efg"
if [ $a = $b ]
then
echo "$a = $b : a 等于 b"
else
echo "$a = $b: a 不等于 b"
fi
if [ $a != $b ]
then
echo "$a != $b : a 不等于 b"
else
echo "$a != $b: a 等于 b"
fi
if [ -z $a ]
then
echo "-z $a : 字符串長度為 0"
else
echo "-z $a : 字符串長度不為 0"
fi
if [ -n $a ]
then
echo "-n $a : 字符串長度不為 0"
else
echo "-n $a : 字符串長度為 0"
fi
if [ $a ]
then
echo "$a : 字符串不為空"
else
echo "$a : 字符串為空"
fi
執(zhí)行
[root@centos6-1 ~]# ./helloworld.sh
abc = efg: a 不等于 b
abc != efg : a 不等于 b
-z abc : 字符串長度不為 0
-n abc : 字符串長度不為 0
abc : 字符串不為空
5. 文件測試運(yùn)算符
操作符 | 意義 |
---|---|
-b file | 文件是否是塊設(shè)備文件哨毁,如果是枫甲,則返回 true |
-c file | 文件是否是字符設(shè)備文件,如果是扼褪,則返回 true |
-d file | 是否是目錄想幻,如果是,則返回 true |
-f file | 文件是否是普通文件(既不是目錄话浇,也不是設(shè)備文件)脏毯,如果是,則返回 true幔崖。 |
-g file | 文件是否設(shè)置了 SGID 位食店,如果是,則返回 true |
-k file | 文件是否設(shè)置了粘著位 (Sticky Bit)赏寇,如果是吉嫩,則返回 true |
-p file | 文件是否是具名管道,如果是嗅定,則返回 true |
-u file | 文件是否設(shè)置了 SUID 位自娩,如果是,則返回 true |
-r file | 文件是否可讀渠退,如果是忙迁,則返回 true |
-w file | 文件是否可寫,如果是智什,則返回 true |
-x file | 文件是否可執(zhí)行动漾,如果是丁屎,則返回 true |
-s file | 文件是否為空(文件大小是否大于 0)荠锭,不為空返回 true |
-e file | 文件(包括目錄)是否存在,如果是晨川,則返回 true |
下面是詳細(xì)例子
#!/bin/bash
file="/com/zaomianbao"
if [ -r $file ]
then
echo "文件可讀"
else
echo "文件不可讀"
fi
if [ -w $file ]
then
echo "文件可寫"
else
echo "文件不可寫"
fi
if [ -x $file ]
then
echo "文件可執(zhí)行"
else
echo "文件不可執(zhí)行"
fi
if [ -f $file ]
then
echo "文件為普通文件"
else
echo "文件為特殊文件"
fi
if [ -d $file ]
then
echo "文件是個目錄"
else
echo "文件不是個目錄"
fi
if [ -s $file ]
then
echo "文件不為空"
else
echo "文件為空"
fi
if [ -e $file ]
then
echo "文件存在"
else
echo "文件不存在"
fi
執(zhí)行
[root@centos6-1 ~]# ./helloworld.sh
文件不可讀
文件不可寫
文件不可執(zhí)行
文件為特殊文件
文件不是個目錄
文件為空
文件不存在
9.流程控制
1.if-else
if condition
then
//做你想做的事
else
//做你想做的事
fi
if condition1
then
//做你想做的事
elif condition2
then
//做你想做的事
else
//做你想做的事
fi
2.case
case 語句匹配一個值或一個模式证九,如果匹配成功删豺,執(zhí)行相匹配的命令
case 值 in
模式1)
//做你想做的事
;;
模式2)
//做你想做的事
;;
*)
//做你想做的事
;;
esac
取值后面必須為關(guān)鍵字 in,每一模式必須以右括號結(jié)束愧怜。取值可以為變量或常數(shù)呀页。匹配發(fā)現(xiàn)取值符合某一模式后,其間所有命令開始執(zhí)行直至 ;;拥坛。;; 與其他語言中的 break 類似蓬蝶,意思是跳到整個 case 語句的最后。取值將檢測匹配的每一個模式猜惋。一旦模式匹配丸氛,則執(zhí)行完匹配模式相應(yīng)命令后不再繼續(xù)其他模式。如果無一匹配模式著摔,使用星號 * 捕獲該值缓窜,再執(zhí)行后面的命令。
3.for
for 變量 in 列表
do
//做你想做的事
done
4.while
while command
do
//做你想做的是
done
5.until
until 循環(huán)執(zhí)行一系列命令直至條件為 true 時停止谍咆。until 循環(huán)與 while 循環(huán)在處理方式上剛好相反禾锤。一般 while 循環(huán)優(yōu)于 until 循環(huán),但在某些時候摹察,也只是極少數(shù)情況下恩掷,until 循環(huán)更加有用。
until command
do
//做你想做的事
done
command 一般為條件表達(dá)式港粱,如果返回值為 false螃成,則繼續(xù)執(zhí)行循環(huán)體內(nèi)的語句,否則跳出循環(huán)查坪。
10.函數(shù)
函數(shù)可以讓我們將一個復(fù)雜功能劃分成若干模塊寸宏,讓程序結(jié)構(gòu)更加清晰,代碼重復(fù)利用率更高偿曙。像其他編程語言一樣氮凝,Shell 也支持函數(shù)。Shell 函數(shù)必須先定義后使用望忆。
#!/bin/bash
demoFun(){
echo "這是我的第一個 shell 函數(shù)!"
}
echo "-----函數(shù)開始執(zhí)行-----"
demoFun
echo "-----函數(shù)執(zhí)行完畢-----"
執(zhí)行
[root@centos6-1 ~]# ./helloworld.sh
-----函數(shù)開始執(zhí)行-----
這是我的第一個 shell 函數(shù)!
-----函數(shù)執(zhí)行完畢-----
如果函數(shù)有返回值罩阵,則函數(shù)返回值可以在調(diào)用該函數(shù)后通過 $? 來獲得。