什麼是shell腳本,首先它是一個腳本,並不能做爲正式的編程語言,說白了就是shell腳本就是一些命令的集合。mysql
凡是自定義的腳本建議放到/usr/local/sbin/目錄下,這樣的好處是方便管理和維護,且利於之後交接給接替你的管理員。linux
shell腳本的結構sql
#cat first.shshell
#! /bin/bash編程
## This is my first shell script.數組
datebash
echo "Hello world!"編程語言
腳本要以#! /bin/bash開頭,表明的意思:該文件是使用的是bash語法,若是不使用該行也是能夠的,可是若是把這個腳本放到一個默認shell並不是bash的系統裏,那麼這個腳本頗有多是不能成功執行的。ide
還能夠適當在腳本中使用#寫一些腳本相關的註釋內容,如做者、建立日期或者版本等。這些並非shell腳本必定要的,只是爲了統一管理,規範化。函數
shell腳本的幾種執行方式
fork:直接使用絕對路徑來執行腳本,這種方式會啓動一個子shell來執行腳本。
source filename:在當前shell環境下,讀取並執行filename中的命令。注:該命令可用命令「.」來替代,如:source .bash_rc 與 . .bash_rc 是等效的。
exec 絕對路徑:exec使用shell腳本的絕對路徑在當前shell(shell會被重置到初始環境)下執行腳本,腳本執行完後會退出該shell。
./script啓動一個子shell來執行腳本。
sh|bash filename啓動一個子shell讀取並執行filename中的命令。
子shell的變量結果不會被帶回父shell,因此要想經過腳本設置當前shell的環境變量時,要用source命令。
shell腳本執行方式 |
是否須要執行權限 |
緣由 |
exec |
須要執行權限 |
由腳本主動調用shell來執行命令 |
fork或./ |
||
source或. |
無需執行權限 |
由shell主動讀取腳本並執行 |
bash或sh |
使用sh命令執行一個腳本時,可使用-x參數查看這個腳本的執行過程,在進行腳本調試時,有利於發現問題。
# sh -x first.sh
+ date
Fri Jan 822:28:23 CST 2016
+ echo 'Hello world!'
Hello world!
shell自定義變量
在shell腳本中定義變量,能夠方便咱們很方便的編輯、修改腳本,且使腳本變得簡潔。
格式:變量名=值
shell數學運算
在shell中進行數學運算時,須要使用$[]括起來。
乘法運算:
# a=8;b=3;echo "$a*$b=$[$a*$b]"
8*3=24
除法運算
# a=8;b=3;echo "$a/$b=$[$a/$b]"
8/3=2
默認shell是不支持小數的。若是須要小數,則須要調用bc(linux 系統中的計算器)「yum –y install bc」
bc不會進行四捨五入。
若是想要保留2位小樹,能夠這樣實現。
# echo "scale=2;8/3"|bc
2.66
shell用戶交互
shell腳本能夠實現讓用戶輸入一些字符串(read命令)或者讓用戶去選擇(select語句)的行爲。
read命令
# cat read.sh
#! /bin/bash
## Using 'read' in shell script.
read -p "Please input a number: " x
read -p "Please input another number: " y
sum=$[$x+$y]
echo "The sum of the two numbers is: $sum"
read命令相似與visualbasic的input函數,做用是產生一個「輸入行」,將用戶輸入的字符串賦值給read命令語句後的變量。
# sh read.sh
Please input a number: 2
Please input another number: 10
The sum of the two numbers is: 12
select語句
select 循環提供了一個簡單的方法來建立一個編號的菜單,用戶可從中選擇。它是有用的,當你須要從列表中選擇,要求用戶選擇一個或多個項目。
select 表達式是一種bash的擴展應用,動做包括:
l 自動用1,2,3,4列出菜單(沒有echo指令,自動顯示菜單)
l 自動read輸入選擇(沒有 read指令,自動輸入)
l 賦值給變量(沒有賦值指令,自動輸入數字後,賦值字符串給變量)
語法格式:
selectvariable in value1 value2 value3 …
do
command
done
例子:
# cat sel.sh
#! /bin/bash
echo "What is your favourite OS?"
select var in "Linux" "Gnu Hurd" "FreeBSD" "Other"
do
break
done
echo "You have selected $var"
# sh sel.sh
What is your favourite OS?
1) Linux
2) Gnu Hurd
3) Free BSD
4) Other
#? 2
You have selected Gnu Hurd
select自己就是一個循環,break就是當選擇後,就跳出循環。
當變量內容含有空格時,應該將其用""括起來。
select通常和case語句結合使用,以上面一個例子爲例,將它優化下:
# cat sel.sh
#! /bin/bash
echo "What is your favourite OS?"
select var in "Linux" "Gnu Hurd" "FreeBSD" "Other"
do
case $var in
Linux)
break;;
"Gnu Hurd")
break;;
"Free BSD")
break;;
Other)
break;;
*)
echo "Please enter anumber:(1-4)";;
esac
done
echo "You have selected $var"
select雖然循環卻在第一次選擇以後再也不顯示菜單,只循環輸入。
# sh sel.sh
What is your favourite OS?
1) Linux
2) Gnu Hurd
3) Free BSD
4) Other
#? 6
Please enter a number:(1-4)
#? 8
Please enter a number:(1-4)
#? 3
You have selected Free BSD
Shell腳本預設變量
# cat option.sh
#! /bin/bash
sum=$[$1+$2]
echo "$0$1"+"$2"="$sum"
# sh option.sh 2 3
option.sh 2+3=5
$#表示參數的個數,$0是腳本自己的名字,$1是執行腳本時跟的第一個參數,$2是執行時跟的第二個參數,$3是…固然一個shell腳本的預設變量是沒有限制的。
if語句
if語句是邏輯判斷語句。
if幾種語法格式:
1) if 判斷語句;then command;fi
2) if 判斷語句;then command;else command;fi
3) if 判斷語句
then
command
fi
4) if 判斷語句
then
command
elif 判斷語句
then
command
else
command
fi
例子
# cat if1.sh
#! /bin/bash
read -p "Please input your score: " a
if ((a<60)); then
echo "You didn'tpass the exam."
Fi
if判斷語句的相關內容
在進行數值關係運算時,除了可使用(())的形式外,還可使用[],但不能使用>,<,=,!=這些符號,要使用-lt(小於),-gt(大於),-le(大於等於),-ge(大於等於),-eq(等於),-ne(不等於)。
再使用[]時要注意空格。
例子
# cat if1.sh
#! /bin/bash
read -p "Please input your score: " a
if [ $a –lt60 ]; then
echo "You didn't pass theexam."
Fi
在判斷語句中可使用&&(而且)、||(或者)、!(非)
# a=10; if [ $a -lt 1 ] || [ $a -gt 5 ]; then echo OK; fi
OK
# a=5; if [ $a -gt 1 ] && [ $a -lt 10 ]; then echo OK; fi
OK
和文件相關的判斷參數
-e :判斷文件或目錄是否存在
-d :判斷是否是目錄,並是否存在
-f :判斷是不是普通文件,並是否存在
-r :判斷文檔是否有讀權限
-w :判斷是否有寫權限
-x :判斷是否可執行
例子:
# if [ -x/bin/bash ]; then echo ok; fi
ok
# if [ ! –x/bin/bash ];then chmod +x /bin/bash;fi
和變量相關的判斷參數
-n:判斷變量是否不爲空
-z:判斷變量是否爲空
==或=:判斷變量的值是否爲指定值
!=:判斷變量的值是否非指定值
例子:
# a=;if [ -n "$a" ]; then echo "a is not null";else echo "a is null"; fi
# a=;if [ -z $a ]; then echo "a is null"; fi
a is null
判斷條件也能夠是一條命令
例子:
# if grep -q '^mysql:' /etc/passwd;then echo"user mysql exitst.";fi
user mysqlexitst.
grep –q的做用是,過濾但不輸出。
case選擇語句
語法格式:
case 變量 in
value1 |value2)
command
;;
value3)
command
;;
value4)
command
;;
*)
command
;;
esac
上面的結構中,不限制 value 的個數,可使用|匹配多個值,*則表明除了上面的 value 外的其餘值。
例子:
# cat case.sh
#! /bin/bash
read -p "Input a number: " n
a=$[$n%2]
case $a in
1)
echo "The number isodd."
;;
0)
echo "The number iseven."
;;
*)
echo "It's not anumber!"
;;
esac
這是一個判斷奇偶數的腳本,%在shell中是做爲取餘的符號。
for循環語句
for 變量名 in 循環的條件; do
command
done
這裏的「循環的條件」能夠寫成一組字符串或者數字(用 1 個或者多個空格隔開), 也能夠是一條命令的執行結果,注意要使用反單引號``.
# for i in 1 2 3 a b; do echo $i; done
1
2
3
A
B
# for i in `seq 1 5`; do echo $i;done
1
2
3
4
5
seq命令:用於產生從某個數到另一個數之間的全部整數
# seq 1 5
1
2
3
4
5
while循環語句
while循環語句經常用來編寫死循環的腳本,用於監控某項服務。
語句格式:
while 循環條件;do
command
done
例子:
# cat while.sh
#! /bin/bash
a=5
while [ $a -ge 1 ]; do
echo $a
a=$[$a-1]
done
把循環條件用一個:(冒號)替代,這樣能夠作到死循環
# cat load.sh
#!/bin/bash
shu=1
while : ; do
load=`uptime|awk '{print$(NF-2)}'|cut -d. -f1`
if [ $load -gt 10 ]&& [ $shu -le 4 ] ;then
echo "system load is high."|mail -s"system load" admin@139.com
shu=$[$shu+1]
sleep 30
elif [ $shu -gt 4 ];then
shu=1
sleep 3600
else
shu=1
sleep 30
fi
done
這是一個監控系統負載的腳本。沒30秒檢測一次系統負載,若是負載值高於10時,向admin@163.com發一封告警郵件,若是連續4次負載高於10時,則休眠1小時再繼續執行腳本,以免頻繁發送郵件,對管理員形成騷擾(告警收斂)。
break、continue、exit
break:退出本層循環
continue:跳過接下來的語句,直接進入下一次循環
exit:退出當前shell
#!/bin/bash
for i in `seq 1 5`;do
echo $i
if [ $i== 3 ];then break ;fi
echo $i
done
echo aaaaaaa
# sh break.sh
1
1
2
2
3
aaaaaaa
#!/bin/bash
for i in `seq 1 5`;do
echo $i
if [ $i== 3 ];then continue ;fi
echo $i
done
echo aaaaaaa
# sh continue.sh
1
1
2
2
3
4
4
5
5
aaaaaaa
#!/bin/bash
for i in `seq 1 5`;do
echo $i
if [ $i== 3 ];then exit ;fi
echo $i
done
echo aaaaaaa
# sh exit.sh
1
1
2
2
3
shell函數
函數就是把一段代碼整理到一個小單元中,並給這個小單元起一個名,當用到這段代碼時,直接調用這個小單元的名字便可。
函數格式:
function_name() {
command
}
函數應定義在shell腳本的開頭
# cat sum.sh
#! /bin/bash
sum() {
echo$1"+"$2"="$[$1+$2]
}
sum 3 4
# sh sum.sh
3+4=7
獲取網卡名對應的IP:
# cat ip.sh
#!/bin/bash
ip() {
ifconfig |grep -A1"$1 " |tail -1 |awk '{print $2}'|awk -F':' '{print $2}'
}
read -p "Please input the eth name: " e
myip=`ip $e`
echo "$e address is $myip"
# sh ip.sh
Please input the eth name: lo
lo address is 127.0.0.1
shell數組
定義元素:
name[下標]=value
ü 下標從0開始
定義數組:
name=(value1value2 value3 …)
刪除數組:
unset name
刪除元素:
unset name[下標]
打印數組的全部元素:
echo${name[*]}或echo ${name[@]}
與打印變量不一樣,打印數值時須要使用${}將數組擴起來
打印數組:
echo${name[下標]}
打印第2個元素: echo ${a[1]}
打印數組的元素個數:
Echo${#name[@]} 或者 echo ${#a[*]}
數組分片:
echo${name[*]:下標x:下標y}
限制數組的打印範圍,打印下標x到下標y之間的元素
數組替換:
echo ${name[@]/value1/value2}
更改數組的輸出,將value1替換爲value2
name=(${name[@]}/value1/value2)也能夠經過這種形式進行賦值