bash腳本編程
腳本文件格式:
第一行頂格:#!bin/bash (shebang)
注釋信息:以#開頭
代碼注釋:好的程序員必備
適量的添加縮進或添加空白行以示分割
語言:編程語言格式:庫,算法和數據結構
編程思想:
能夠把學到的編程語言的語法格式隨時轉換為解決問題的思路
問題空間–》解空間
什么是變量
變量是bash環境或腳本編程中是非常重要的東西,linux是多用戶多任務的的操作環境,用戶需要調用變量的只來進行操作
變量就是一些特定的字符串,只不過不表示原有的意思, 比如:“name=magedu” 就是一個變量,就用一個簡單的字符來代替另一個比較復雜或則比較容易更改變動的值,這就是變量
系統自帶有很多變量,可使用set或declare查看。
變量:
局部變量:作用域為某代碼片段
本地變量:作用域為當前shell進程
環境變量:作用域為當前shell及其子shell
位置參數變量:向執行腳本的shell教程傳遞參數
特殊變量:shell內置的有特殊功能的便令
變量的命名規則
1.變量名稱不能以數字開頭,可使用字母數字下劃線
2.變量命令盡量見名知義
3.使用標準命名規則:駝峰命令法
4.不能使用系統中只帶的關鍵字(如cd、if、ehco……)
數據類型;
字符型,數值型,(精確數值,整數,近似數值(浮點數(單精度、雙精度)))
shell:弱類型,默認把所有字符都表示為字符型
注:shell本身不支持浮點數運算,只能借助其他工具
#animal=dog
#echo “${animal}s”
引用:#PATH=“$PATH:/usr/local/apche/bin”
算術運算:+、-、*、/、%
1、let var=$num1 op $num2 == let var=expression
op:操作運算符(+、-、*、/、%)
2、var=$[experssion]
3、var=$((experssion))
4、var=$(expr arg1 arg2 arg3)
注意: 一個小括號表示命令引用
有些時候乘法需要轉義
不加var則表示直接運算
增強型賦值:變量做某種算術運算后,回存到此變量中
1、declare -i i=1
i=$[$i+1] 在自身加1
2、let i=$i+# #=數字
let i+=#
+=、-=、*=、/=、%= //此用法一般用在let在shell腳本中
自增
var=$[$var+1]
let var+=1
let var++
自減
var=$[$var-1]
let var-=1
let var–
條件測試:
判斷某需求是否滿足,需要由測試機制來實現
如何編寫測試表達式實現所需的測試
(1)執行命令,并利用命令狀態返回值來判斷
0:成功
1~255:失敗
#who | grep "^centos\>" #echo $? #1
(2)測試表達式
test expression
#test 2 > 3 #echo $? #1
[experssion]
[[ experssion ]]
注意:experssion兩端必須有空白字符,否則為語法錯誤
bash的測試類型
數值類型:
比較數值
-eq :是否等于 #[ $num1 -eq $num2 ]
-ne:是否不等于
-gt:是否大于
-ge:是否大于等于
-lt:是否小于
-le:是否小于等于
字符串測試:(ascll)碼表來判斷比較
字符比較(通常來判斷字符是否為空)
== 是否等于 #[ tom == Tom ] 判斷str1是否等于str2
>:是否大于 [[ “a” > “b”]]
<:是否小于
!=:是否不等于
=~:左側字符串是否能夠被右側的PATTERN所匹配
注意:比較表達式要寫在中括號中,賦值不寫在中括號中
注意:1、在進行字符串比較時盡可能使用雙中括號 "[[ ]]",單中括號有時不能識別
2、字符串要加引號 (如果有變量則雙引,無則單引)
3、作比較時要使用雙中括號 “[[ ]]”
#name=tom # [[ "$name" =! "o" ]] //注意此為字符O #echo $? #0 注意:匹配是只要包含有一部分字符即可
-z “string” :判斷指定的字符串是否為空,空則真,不空則假
-n "string" :判斷指定的字符串是有不空,不空則真,空則假
腳本的返回值:
默認是腳本中執行的最后一條命令的狀態返回值
自定義狀態范圍值(退出狀態碼)
exit n :n為自己指定的狀態碼
0:成功
!0:失敗
注意:shell進程遇到exit時即會終止,因此整個腳本執行即為結束
文件測試:做文件的存在性、權限、等相關測試
存在性測試:
-a file
-e file
#[ -e /path/to/somefile ] //測試文件的存在性測試,存在則為真,否則為假
文件存在性及類型測試:
-b file :是否存在并且為塊設備文件
-c file :是否存在并且為字符文件
-d file :是否存在并且為目錄文件
-f file :是否存在并且為普通文件
-h 或 -L file :是否存在并且為符號鏈接文件
-p file :是否存在并且為管道文件
-s file :是否存在并且為套接字文件
# [ -b /dev/sda ]
文件權限測試:
-r file:是否存在并且可讀(針對當前用戶可讀)
-w file:是否存在并且可寫(針對當前用戶可寫)
-x file:是否存在并且可執行(針對當前用戶可執行)
文件特殊權限測試:
-g file :是否存在并且擁有SGID權限
-u file :是否存在并且擁有SUID權限
-k file :是否存在并且擁有STICKY權限
#[ -k /usr/bin/passwd ]
#echo $?
#0
文件是否有內容:
-s file :是否有內容 (有則真,無則假)
時間戳做測試:
-o file :當前用戶是否為文件的屬主(owner)
-G file :當前用戶是否為文件的屬組
雙目測試:
file1 -ef file2 :file1與file2是否為指向同一個文件系統的相同inode的硬鏈接
file1 -nt file2 : file1 與file2 誰更新(指修改時間(mtime)距離這一刻的時間)
file1 -nt file2 : file1 是否舊于 file2 (指修改時間(mtime)距離這一刻的時間)
組合條件測試:
邏輯運算
第一種方式:
COMMAND1 && COMMAND2
//兩者必須成立才為真,否則為假
COMMAND1 || COMMAND2
//l兩者其中一個成立則為真
!COMMAND
//將原有得出的結果取反,則本來命令的狀態結果為0,則取反為非0。(命令為真則為假,命令為假則為真)
#[ -o file ] && [ -r file ] //文件是否為屬主并可讀
第二種方式:
與(&&):[experssion -a experssion ] 可使用單中擴或雙中擴
或(||): [experssion -a experssion ]
非(?。?!experssion
#[ -o file -a -x file ] //的當前用戶是否為指定文件的屬主并且擁有執行權限
練習:將當前主機名稱保存至hostname變量中:
1、判斷主機名如果為空,或者為localhost.localdomain,則將其設置為www.magedu.com
#hostName=$(hostname) #[ -z "hostname" -o "$hostname" == "localhost.localdomain" -o "$hostname" == "localhost" ] && hostname=www.magedu.com
向腳本傳遞參數:(就是用位置參數變量實現)
位置參數變量
當運行ls命令時,后面跟上/etc/var。這就是位置參數,
那我們在程序中怎么知道對方給我們的是什么參數呢,就把代碼作用在參數上呢?
比如命令ls,必須要能夠獲取用戶從命令行傳遞過來的參數,并且能夠讓ls內部的某些代碼作用在這個參數上,而像這些傳遞給命令的參數,這就叫做位置參數
對于shell腳本來說確實是引用位置參數的
寫腳本:muscripts.sh argu1 argu2 ….. 在腳本中可以直接引用,只要用戶傳遞了就可以在直接引用他們,引用方式就是$1、$2
$1表示引用整個腳本的位置參數當中的第一個,自動的會保存在$1中
$2表示第二個參數
$3….
例:1.希望用戶從命令行隨便給兩個參數,能夠求出兩個整數之和
#vi sum.sh
#!/bin/bash
echo $[ $1+$2 ]
#bash sum.sh 2 7
#9
注意:位置參數如果比較多,一直到10或以上,則需要使用花括號“{}” 如:${10}
輪替:
shift [n] :位置參數輪替
每一次shift就能踢掉此前的對應的第一位的參數,只踢第一個,n為2則踢前兩個,不能指定為哪一位,4就是前3個
特殊變量:
$0:腳本文件路徑(所執行的腳本路徑本身)
#vim filename.sh
#!/bin/bash
basename $0 //取文件基名(文件本身的名字)
#chmod +x filename.sh
#./filename.sh
$#腳本參數的個數
#vim filename.sh
#!/bin/bash
echo $1 $2
echo $# //顯示出參數的個數
#./filename.sh hello world
#hello world
# 2
注意:即使我們不顯示$1、$2等對應的參數,依然也可以使用$#來引用腳本參數的個數
$*:腳本的所有參數
把所有參數當做一個分別的子符串
$@:腳本的所有參數
把所有參數當做一個整體的子符串
$?:上一個語句的狀態返回值
過程式編程語言的代碼執行順序
順序執行:逐條運行
選擇執行;代碼存在一個或多個分支,只執行其中一個
代碼有一個分支:條件滿足時才會執行
代碼有兩個或以上分支:只會執行其中一個滿足其條件的分支
循環執行
代碼片段(循環體)要執行0、1、或多個來回
選擇執行:
單分支if語句:
if 測試條件;then
代碼分支 //如果測試條件成立,則執行此代碼分支
fi //結束
多分支if語句:
if 測試條件;then
條件為真時執行的分支
else
條件為假時執行的分支
fi
例:通過參數傳遞一個用戶名給腳本,此用戶不存在時,則添加
#vim useradd.sh #!/bin/bash if [$# -lt 1];then echo "xxxx" exit 100 fi if ! grep "^$1\>" /etc/passwd &> /dev/null ;then useradd $1 echo $1 | passwd --stdin $1 $> /dev/null echo "xxxxx" $1 finished!" fi #./useradd.sh user1
多分支case條件語句
case語句和if elif else 語句一樣都是多分支條件語句,不過和if多分支條件語句不同的是case語句只能判斷一種條件關系,而if語句可以判斷多種條件語句
case $變量名 in
”值1“) //如果變量的值等于值1,則執行程序1
;;
“值2”) //如果變量的值等于值2,則執行程序2
;;
“值3” ) //如果變量的值等于值3,則執行程序3
;;
*) //如果變量的值與之前的都不匹配,則執行此語句
;;
esac //case語句結束符
case支持glob風格的通配符
* :任意長度任意字符
?:任意單個字符
[]:指定范圍內的任意單個字符
a|b:a或則b
查看當前shell中的變量
set
查看當前shell中的所有環境變量
printenv
env
export
定義環境變量:
ANIMALS=pig
ANIMALS=$ANIMALS:goat
ANIMALS=$ANIMALS:sheep
echo $ANIMALS
export PATH=$PATH:/usr/local/apache/bin
export PATH=/usr/local/apache/bin:$PATH
腳本:命令的堆砌,按實際需要,結合命令流程控制機制實現的源程序
ctrl+v [ 代替033 (033為隱藏不可見字符)
腳本調試
bash -n /p/t/some_script
檢測腳本中的語法錯誤
bash -x /p/t/some_scripts
調試執行
root
PATH目錄
.bash_profile
直接定義變量
name=XXX
撤銷
unset name
原創文章,作者:Lii,如若轉載,請注明出處:http://www.www58058.com/34306
態度決定高度,望以后能按時提交。