領導安排要做一個數據庫的自動備份計劃。閒來沒事先學習一下linux的shell,後期再結合rman備份腳本來給領導一個交代。
shell的語法如下:
#!/bin/sh --shell開始
#this is my first shell --#表示該shell的註釋 也可寫在代碼中間
echo "Please enter your name:" --命令和控制結構
read NAME
echo "$NAME need help!!"
這樣就寫好了一個簡單的shell腳本了。
執行腳本的方法: ./shellname or sh shellname
其中:
sh -x shellName --執行該腳本顯示所有變量的值
sh -n shellName --不執行腳本只檢查語法,返回所有的語法錯誤
注意:在執行前應檢查該腳本的執行權限。
下面介紹下 shell的變量:
shell的變量(2種):
1:臨時變量:在shell程序內部定義的變量,範圍爲定義它的程序。其他程序不可見。包括兩種內型
用戶自定義變量:如:上面腳本中 NAME
位置變量:
2:永久變量:系統的環境變量。不會隨shell結束而消失。如:$HOME,$JAVA_HOME,$PATH ...
變量賦值:
定義是賦值: NUM=100
將一個命令的執行結果賦值:TIME=`date`
將一個變量賦值給另一個變量: VAR1=VAR2
將字符串的值賦值個變量:NAME="jack" or NAME='jack'
單引號 和 雙引號的區別:
在使用雙引號時如果變量值裏有另一個變量b,b會顯示它的值:
-bash-3.2# echo $TIME
2012-08-09
-bash-3.2# TEST="jack and time $TIME"
-bash-3.2# echo $TEST
jack and time 2012-08-09
單引號則不會。
對變量進行操作的命令:
在終端可使用echo查看變量值: echo $TIME
set 可查看系統中所有已經定義的變量
unset varName 刪除變量
shell解釋執行用戶命令式。將命令行的第一個部分作爲命令名,其他部分作爲參數;
位置變量:出現在命令行上的位置確定的參數稱爲 位置參數。如:
ls -l file1 fiel2 file3 ..file9
$0 這個命令本身,包括參數: ls -l
$1 file1
$2 file2 以此類推,最大到 9個參數。
特殊變量:
$* 這個shell程序的所有參數
$# 這個shell程序的參數個數
$$ 這個shell程序的PID
$! 執行上一個後臺命令的PID
$? 執行上一個命令的返回值 0表示上個命令執行成功 非0表示不成功
例子:
special_var.sh:
#!/bin/sh
#this is a example for special_var
echo '$* is--' $*
echo '$# is--' $#
echo '$$ is--' $$
echo '$! is--' $!
echo '$? is--' $?
echo '$0 is--' $0
echo '$1 is--' $1
輸出結果爲:
-bash-3.2# ./special_var.sh file1 file2 file3
$* is-- file1 file2 file3
$# is-- 3
$$ is-- 4096
$! is--
$? is-- 0
$0 is-- ./special_var.sh
$1 is-- file1
變量相關的就這麼多了 下面來看看shell常用命令:
read varName --在執行shell時,交互式的讀取數據並賦值給varName
expr --對整數型變量進行算術運算 + - \* (乘法) /(除法)
test 測試條件 --測試變量是否相等,是否爲空,文件類型...
範圍: 整數 字符串 文件
常見字符串測試:
-z string 字符串string 爲空串(長度爲0)時返回真
-n string 字符串string 爲非空串時返回真
str1 = str2 字符串str1 和字符串str2 相等時返回真
str1 == str2 同 =
str1 != str2 字符串str1 和字符串str2 不相等時返回真
str1 < str2 按字典順序排序,字符串str1 在字符串str2 之前
str1 > str2 按字典順序排序,字符串str1 在字符串str2 之後
常見整數測試:
int1 -eq int2 如果int1 等於int2,則返回真
int1 -ne int2 如果int1 不等於int2,則返回真
int1 -lt int2 如果int1 小於int2,則返回真
int1 -le int2 如果int1 小於等於int2,則返回真
int1 -gt int2 如果int1 大於int2,則返回真
int1 -ge int2 如果int1 大於等於int2,則返回真
文件測試:
-b filename 當filename 存在並且是塊文件時返回真(返回0)
-c filename 當filename 存在並且是字符文件時返回真
-d pathname 當pathname 存在並且是一個目錄時返回真
-e pathname 當由pathname 指定的文件或目錄存在時返回真
-f filename 當filename 存在並且是正規文件時返回真
-g pathname 當由pathname 指定的文件或目錄存在並且設置了SGID 位時返回真
-h filename 當filename 存在並且是符號鏈接文件時返回真 (或 -L filename)
-k pathname 當由pathname 指定的文件或目錄存在並且設置了"粘滯"位時返回真
-p filename 當filename 存在並且是命名管道時返回真
-r pathname 當由pathname 指定的文件或目錄存在並且可讀時返回真
-s filename 當filename 存在並且文件大小大於0 時返回真
-S filename 當filename 存在並且是socket 時返回真
-t fd 當fd 是與終端設備相關聯的文件描述符時返回真
-u pathname 當由pathname 指定的文件或目錄存在並且設置了SUID 位時返回真
-w pathname 當由pathname 指定的文件或目錄存在並且可寫時返回真
-x pathname 當由pathname 指定的文件或目錄存在並且可執行時返回真
-O pathname 當由pathname 存在並且被當前進程的有效用戶id 的用戶擁有時返回真(字母O 大寫)
-G pathname 當由pathname 存在並且屬於當前進程的有效用戶id 的用戶的用戶組時返回真
file1 -nt file2 file1 比file2 新時返回真
file1 -ot file2 file1 比file2 舊時返回真
f1 -ef f2 files f1 and f2 are hard links to the same file
邏輯測試
-a 邏輯與,操作符兩邊均爲真,結果爲真,否則爲假。
-o 邏輯或,操作符兩邊一邊爲真,結果爲真,否則爲假。
! 邏輯否,條件爲假,結果爲真。
awk --用於指定數據的分割符。默認爲 空格
awk --用於指定數據的分割符。默認爲 空格
-bash-3.2# grep ^root /etc/passwd
root:x:0:0:root:/root:/bin/bash
-bash-3.2# awk -F: '$3==0 {print $1}' /etc/passwd --不是轉義符,是單引號。$3和$1是awk命令自己定義的變量和位置變量無關
root
在來看看shell的控制結構:
if 語句
#!/bin/sh
#this is example for if..else
scores=40;
if [ $scores -gt 90 ]; then
echo "very good!";
elif [ $scores -gt 80 ]; then
echo "good!";
elif [ $scores -gt 60 ]; then
echo "pass!";
else
echo "no pass!";
fi;
the result is "no pass!"
shell命令,可以按照分號分割,也可以按照換行符分割。如果想一行寫入多個命令,可以通過“';”分割。
其中的 [[ 和 [ (或者test)是有區別的
如:
[chengmo@centos5 ~]$ a=5;if [[ a -gt 4 ]] ;then echo 'ok';fi;
ok
exit --退出程序執行。0爲正常退出:exit 0,非0爲非正常退出;
for … in 語句
for 變量 in 空格隔開的字符串如: a b c
do
命令語句
done
說明:seq字符串 只要用空格字符分割,每次for…in 讀取時候,就會按順序將讀到值,給前面的變量。
$(seq 10) 產生 1 2 3 。。。。10空格分隔字符串。
例如:
#!/bin/sh
#this is example for for1
for i in $(seq 10); do
echo $i;
done;
for((賦值;條件;運算語句))
for((賦值;條件;運算語句))
do
命令
done;
例子:
#!/bin/sh
#this is example for for2
for((i=1;i<=10;i++));do
echo $i;
done;
while語句結構
while 條件語句
do
命令
done;
例子:
#!/bin/sh
i=10;
while [ $i -gt 5 ];do
echo $i;
((i--));
done;
實例2:(循環讀取文件內容:)
#!/bin/sh
while read line;do
echo $line;
done < /etc/hosts;
until 循環:
until 條件
do
action
done
意思是:直到滿足條件,就退出。否則執行action.
例子:
#!/bin/sh
a=10;
until [[ $a -lt 0 ]];do
echo $a;
((a—));
done;
select循環:
select 變量 in 關鍵字
do
命令
done
例子
#!/bin/sh
#this is example for select
echo "what is you select"
select VAR1 in "a" "b" "c"
do
break --跳出整個循環
done
echo "you selected $VAR1 !"
case ... esac語句:
case 變量 in
字符串1) 命令列表1
;;
。。。
字符串2) 命令列表2
;;
esac
例子:
#!/bin/sh
#this is example for case
echo "***********"
echo "Please select your operation"
echo "press c to copy"
echo "press d to delete"
echo "************"
read op
case $op in
c)
echo "your selected is copy!"
;;
d)
echo "your selected is delete!"
;;
*) --其他選項用*
echo "incalide selection!!"
esac
一般情況select和case是一起使用的:例如:
#!/bin/sh
select ch in "begin" "end" "exit"
do
case $ch in
"begin")
echo "start something"
;;
"end")
echo "stop something"
;;
"exit")
echo "exit"
break;
;;
*)
echo "Ignorant"
;;
esac
done;
可以參考系統自帶shell 如:/etc/rc.d/init.d/httpd
爲了shell有良好的可讀性 可用 函數
格式:
函數名(){
命令序列
}
調用函數是不帶();如:函數名 參數1 參數2...
函數裏不能有局部變量 只能是全局變量(在shell程序裏的變量)
要讓普通用戶執行權限:
sh shellName
1:對腳本有r權限
2:對腳本的所在目錄有rx權限
./ 腳本
1:對腳本有rx權限
2:對腳本所在目錄有rx權限