Linux腳本基礎
過程式編程:以指令為中心,數據服務於指令,用戶編程時,關註的是指令的本身,第一步,第二步都分別做的什麽
對象式編程:以數據為中心,指令服務於指令,用戶編程時,關註的則是數據的結果,不註重指令的執行過程,適合處理大型
項目
shell程序:將命令按照邏輯關系順序的寫入到腳本中
計算機:運行二進制指令
編程語言:
低級:匯編
高級:
編譯:高級語言-->編譯器-->目標代碼 (將字符串轉換成二進制文件執行,轉換過程利用編譯器)
java,C#...
解釋:高級語言-->解釋器-->機器代碼 (不需要生成二進制文件,輸入字符串,後臺會將字符串轉換為二進制機器碼,生成在內存中)
shell,perl,python...
編程基本概念:
順序執行 (比如:寫一個指令,兩個指令,就會按照順序執行)
循環執行 (比如:創建100個賬號,就是把創建賬號的指令執行100次,就可以使用循環執行)
選擇執行 (比如:當滿足某一個條件執行一個指令,當不滿足一個指令滿足別的條件的時候執行另外一個指令)
shell編程:
各種系統命令的組合
數據存儲:變量,數組
表達式: a + b
語句:if
shell腳本:適合於大批量的重復工作
包含一些命令或聲明,並要符合一定的格式的文本文件
格式要求:首行shebang機制(#!shell類型)如下
#!/bin/bash
#!/usr/bin/python
#!/usr/bin/perl
shell腳本用途:
自動化常用命令
執行系統管理和故障排除
創建簡單的應用程序
處理文本或文件
創建shell腳本:
第一步:使用編輯器來創建文本文件
腳本一般都設為".sh"後綴
第一行必須包括shell聲明序列:#!也就是shebang機制
#!/bin/bash
添加註釋:(可以理解為腳本的一些介紹,用處)註釋是以"#"開頭,建議使用以下註釋內容
#!/bin/bash
#-------------------------------
#Filename: "腳本名稱"
#Revision: "腳本版本"
#Date: "創建日期"
#Author: "作者"
#Email: "郵箱"
#Description: "腳本描述"
#-------------------------------
第二步:運行腳本
賦予腳本執行權限chmod +x "腳本名"
腳本基本結構:
#!SHEBANG (shebang機制)
CONFIGURATION_VARIABLES (變量)
FUNCTION_DEFINITIONS (函數)
MAIN_CODE (其他指令)
腳本例子:
顯示當前主機的各個配置信息
vim hostinfo.sh
#!/bin/bash
#Author: Fang
#Date: 2017-11-23
#Description: show system info
echo "This is hostname is `hostname`"
echo "The Kernel version is `uname -r`"
echo "The CPU version is `lscpu | grep "Model name" | tr -s " " | cut -d: -f2` "
echo "The Mem size is `cat /proc/meminfo | head -1 | tr -s " "`"
echo "The host ip is `ifconfig ens33 | grep "netmask" | tr -s " " | cut -d " " -f3`;netmask is `ifconfig ens33 | grep
"netmask" | tr -s " " | cut -d " " -f5`;"
如果想要每次直接打出腳本名就執行的話需要加入到$PATH變量中
操作步驟:查看當前系統$PATH值,然後使用mv命令將腳本移動到任意一個目錄中即可
如果腳本中有一條命令輸入錯誤,不會影響後續命令的執行,但有時候錯誤過於嚴重就會終止後續命令的執行
在腳本寫完將要執行前,輸入"bash -n "腳本名稱""可以檢測腳本中是否有錯
而要觀察腳本執行過程的話使用bash -x 腳本名稱,會顯示執行順序和每一條命令的執行結果,但前提是腳本執行無誤
變量的大概意思就是會變化的內容
變量名稱:
1 只能使用字母,數字以及下劃線,但不能使用數字開頭
2 不要使用關鍵字,就是在Linux中已經有含義的字符,也不推薦字母做變量,不然後期看腳本容易混亂,如果像學生姓名這種變量名可以起
student_name一目了然,或者是駝峰法,也就是大小寫,駝峰法又分為大駝峰,小駝峰,大駝峰代表只要是單詞的首字母都大寫,小駝峰代表第一個單詞
的字母小寫,後續單詞的首字母大寫
弱類型:寫程序時不需要規定數據類型,系統自動
變量賦值:name='value'(建議使用單雙引號引起變量值,變量值也可以是命令,但要用反向單引號引起來或者$(value))
變量值也可以是一篇文章或者多條數據,但是引用的時候要加給變量加雙引號!!否則就會丟失一些信息
變量賦值時兩邊不要加空格,當不用一個變量的時候使用unset "變量名(不需要加$符號)"刪除;
如果要將一個變量的值賦給另一個變量,則需要加$符號,比如"i=100"當我們想把i的值給j的時候就可以寫成"j=$i",這樣j就有了i的值,如果更改了
i的值或者刪除了i的值,不會影響$j的值
變量的種類:
局部變量:子進程不能調用父進程的局部變量,父進程也不能調用子進程的局部變量
只是在當前shell環境下使用,當前shell表示了一個進程也就是bash,使用"echo $$"可以查看當前所在bash的進程號,也可以使用"pstree -p"命令
查看,進程與進程的關系會以倒樹形結構顯示的非常詳細,排在左面的就是右邊的父進程,越往右就是子進程
bash命令會開啟一個shell,在一個shell中再次開啟一個shell,那麽後面的這個shell就是前面bash的子進程
使用echo $PPID可以查看父進程的進程號,父進程如果關閉,那麽子進程也會停止運行,子進程關閉不影響父進程運行,如果父進程關閉子進程沒有關
閉的話則說明了這個子進程也成為了僵死進程,進程會占用內存空間,所以要殺掉僵死進程釋放資源
環境變量聲明,賦值:
在父進程上定義的變量,一旦聲明為環境變量,就可以一直繼承到下面的進程,如果改了會影響當前的變量和後面的變量,但是父進程的變量不會改
set看到的是所有變量
env和declare -x和export和printenv都可以看到所有環境變量
$SHLVL 可以看到shell的嵌套深度
$_ 代表上一個命令的最後一個參數
只讀變量:
只能聲明,但不能修改和刪除
聲明只讀變量:readonly "變量名稱"或者declare -r "變量名稱"
查看只讀變量:readonly -p或者declare -r
舉例說明:
[root@Centos7 bin]#name=test;( echo $name; name=222;echo $name );echo $name
test
222
test
小括號開了個子進程,括號中name的賦值只是在子進程有效,括號結束後,$name的值就又還原了,當想臨時執行命令還不想影響當前工作環境就可以使
用
比如:
( umask 066;touch f3.txt /app ) 意思就是說在不改變當前umask值的情況下,使新創建的文件權限為600,而當前環境的umask值還是默認的
判斷前面操作執行成功或者失敗:看退出狀態的值
$? : 上一條命令的執行狀態,如果返回值為0那麽說明執行成功,如果返回值為1-255之間的任意一個數,則說明執行失敗,腳本當中 可以人為定
義$?返回的值,使用exit 要返回的值
如果要將一個變量和一個字符一起顯示的話需要加花括號,比如:m=20,n=10,echo ${m}n就會顯示為20n
位置變量:
$1,$2,....:對應第一個參數,第二個參數,第9個以上的參數就要使用"${10},${11}.."這種格式
$0:腳本名稱
$*:代表所有參數 或 $@
$#:代表參數的個數
$@ $*被雙引號引起來的時候才會有差別
$*被雙引號引起來之後會將所有參數作為一個整體
$@被雙引號引起來之後會認為每個參數為獨立字符串
set --:清空所有位置變量
shift:使用shift會將後面的參數推到前面,shift 2:就是將後面兩個參數推到前面
實例:如果每一次創建腳本文件的時候都自動生成註釋可以編寫一個這樣的腳本;
#!/bin/bash
touch $1 (創建一個名為第一個參數的空文件)
chmod +x $1 (給此文件賦予執行權限)
echo "#!/bin/bash
#-------------------------
#Filename: $1
#Revision: 1.1
#Author: Fang
#Date: `date +%F`
#-------------------------" > $1 (將內容輸入到執行腳本後的第一個參數)
#start vim
vim + $1 (編輯第一個參數內容)
bash中的算術運算:help let
+,-,*,/,%(取余),**(乘方)
實現數字運算:
let "表達式" i=10.j=20,let let sum=i+j可以算出值,同時也可以使用[],echo $[1+2],也可以使用(())表示,echo $((1+2))
還可以使用"expr 1 + 2"表達式中間是有空格的,*號需要被轉義,否則會被認為是通配符,如果執行結果是0系統會認為是失敗的
declare -i n=10 ,declare -i m=20(使用declare聲明i是一個數字),可以再使用let sum=m+n
取余數: let n=i%3(取變量i的余數)
數字的次方:let n=2**7 (計算2的7次方)
bash中有隨機生成數生成器:
echo $[$RANDOM%50] 生成的數值為0-49任意一個數
增強型賦值:
let i+=3(把自己加上數值再賦給自己)
let i-=3(把自己減去賦值再賦給自己)
let i++ (相當於i=i+1先取i再++)
let ++i (先++再處理i)
使字符串生成隨機顏色的兩種方法:
1 color=$[RANDOM%7+31];echo -e "\033[${color}m變顏色的字符串\033[0m"
2 color=`seq 31 37 | sort -R | head -n1`;echo -e "\033[1;5;${color}m變顏色的字符串\033[0m"()加上1,5的話可以高亮閃爍
3 如果要在文本中定義一個字符的顏色的話需要以下操作:vim打開一個空文件,輸入"ctrl+v+["然後輸入你要實現的顏色,高亮或者閃爍,比如:vim
color.txt;^[這兩個字符是輸入ctrl+v+[的時候出現的,然後在後面手動輸入[1;5;31m字符串然後繼續ctrl+v+[後面再輸入[0m,也可以使用1或者2
這兩個然後重定向到一個空文件也可以;
邏輯運算:
true,flase
非: ! (取反)
! 1 = 0
! 0 = 1
真:1 假:0
短路與運算: (任何數與0相與都是0)
cmd1 短路與 cmd2
如果cmd1為假,將不執行cmd2
如果cmd1為真,將執行cmd2
短路或運算: (任何數與1相或都是1)
cmd1 短路或 cmd2
如果cmd1為假,將執行cmd2
如果cmd1為真,將不執行cmd2
&&:表示短路與 ||:表示短路或
異或:
異或的兩個值,相同為假,不同為真,比如a=40,b=20那麽echo $[a^b]結果就為真,如果a=40,b=40那麽echo $[a^b]就為假
條件測試:如果某些條件成立了,就返回$?是0,如果條件沒有成立,就返回$?非0
測試命令:
test "表達式" 比如:比較兩個字符是否相同,str1=abc,str2=def,test $str1 = $str2,echo $?,返回值就是非0,兩個值相同就返回0
比較是否不同,str1=abc,str2=def,test $str1 != $str2,echo $?,返回值就是0,如果相同就返回非0
[表達式] 與test測試是等價的相同的,中括號中有字符的時候就返回的是真,如果沒有字符,空的話就是假,可以用來判斷變量是否有值,要
給變量雙引號引起來,[ "x$a" = x ]也可以用這種寫法測試變量是否有值,如果變量有值,那麽兩邊肯定不等,會返回非0值,如果 相等
就會返回0
[]:中括號測試中可以跟的選項
-z 判斷字符串是否為空,如果字符串為空就返回真
-n 判斷字符串是否非空,如果字符串非空就返回真
-v 判斷變量是否有值, 在中括號中變量不用加$符號
-f 判斷中括號中是否為一個文件
-L 判斷中括號中的是否為一個鏈接文件,並且會判斷指向的文件類型
-d 判斷中括號中的是否為一個文件夾
-S 判斷中括號中的是否為套接字文件
-u 判斷suid權限
-k 判斷sticky權限
-v 查看變臉是否有值
-e 判斷文件存在性
-大寫o 判斷當前文件的所有者是否為當前用戶
[-eq]:相等
[-ne]:不等
[-gt]:大於
[-lt]:小於
[-ge]:大於等於
[-le]:小於等於
== 是否等於
> ascii碼是否大於ascii碼
< 是否小於
!= 是否不等於
=~ 用來匹配擴展正則表達式
判斷文件是否可讀並且這個文件是否可寫,如果都滿足就返回true,按照以下方式寫
[ -r /etc/issue ] && [ -w /etc/shadow ] && echo true(有一個不滿足就會顯示false)
[-r /etc/issue -a -w /etc/shadow ] && echo true(跟上面的結果是一樣的)
判斷文件是否可讀或者這個文件是否可寫,滿足任意一條返回true
[-r /etc/issue -o -w /etc/shadow ] && echo true
以下選項都是看實際權限的,包括ACL權限
-r 判斷文件是否可讀
-w 判斷文件是否可寫
-x 判斷文件是否可執行
[[表達式]]可以支持的是擴展的正則表達式
var=haha;[[ "$var" =~ ha(這個ha默認是被包含的意思) ]] && echo true || echo false(返回的值是true,因為$var包含中括號中的那個字
符,所以會返回true)
判斷文件後綴名是否為.sh:filename=f1.sh;[[ "$filename" =~ \.sh$ ]] && echo true || false(返回的值是true,中括號中的內容是正則表
達式,正則表達式不要用雙引號引起來)
判斷ip地址格式是否正確:ip="114.122.2.255";[[ "$ip" =~ ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9]
[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$ ]] && echo true ||echo false
匹配手機號:var=13800138000;[[ "$var" =~ ^1[3456789][0-9]{9} ]] && echo true || echo false
退出狀態碼:
exit [n]:自定義退出狀態碼
腳本中一旦遇到exit命令,腳本就會立即終止;終止退出後$?返回的值取決於腳本中exit後面的值
如果沒有給腳本指定退出狀態碼,腳本的退出狀態碼就會取決於腳本的最後一條命令的執行結果
ls /proc/$$/fd | wc -l(統計當前進程打開的文件描述符)
使用read命令來接受標準輸入,可以實現交互式輸入
比如:read name 會讓你輸入內容,輸入後回車再查看$name就可以看到name的值
也可以同時賦予多個變量,空格做分隔符,平時很少這麽用
-p 指定要顯示的提示
-s 靜默輸入,適用於輸入口令
-n 指定輸入的字符長度,到達限定長度會直接退出
-d '字符' 輸入結束符,看到某一個字符就結束
-t '' 限定超時時間,超過這個值就自動退出,默認以s為單位
bash中處理順序優先級:
1 把命令行分成單個命令詞
2 展開別名(腳本中不許使用別名)
3 展開大括號的聲明({})echo {1..10}會將這種形式展開
4 展開波浪符聲明(~)波浪符表示家目錄,轉換成家目錄
5 命令替換 $() 和 ``會將符號中的命令展開執行
6 再次將命令行分成單詞
7 查看是否有通配符,如果存在繼續展開,也就是用符合條件的文件名代替這些符號(*,?,[abc]等)
8 如果發現含有重定向( < 、 > )則執行重定向
9 最後運行命令
防止擴展:
反斜線(\)轉義符,會將位置參數轉換為普通字符
加引號防止擴展:
單引號('')防止所有擴展
bash的配置文件,當用戶登錄的時候會讀取這些配置文件
按生效範圍劃分,有兩類:
全局配置:
/etc/profile,/etc/profile.d/*.sh,/etc/bashrc(對所有用戶有效)
個人配置:
~/.bash_profile,~/.bashrc (對家目錄的用戶有效)
shell登錄方式:
交互式登錄:
直接通過終端輸入賬號密碼登錄
使用"su - username"切換的用戶
順序執行配置文件:
/etc/profile --> /etc/profile.d/*.sh --> ~/.bash_profile --> ~/.bashrc --> /etc/bashrc
/etc/profile中調用了/etc/profile.d下的文件
~/.bash_profile中又調用了~/.bashrc文件
~/.bashrc又調用了/etc/bashrc文件
非交互式登錄:
su username
圖形化打開終端
執行腳本
開啟其他的bash實例,鍵入bash
順序執行配置文件:
~/.bashrc --> /etc/bashrc --> /etc/profile.d/*.sh
按功能劃分,存在兩類:
profile類和bashrc類
profile類:為交互式登錄提供配置
全局:/etc/profile,/etc/profile.d/*.sh
個人:~/.bash_profile
功能:
(1)用於定義環境變量
(2)運行命令或腳本
bashrc類:為非交互式和交互式登錄提供配置(以下操作都是與用戶相關的,用戶登錄會執行)
全局:/etc/bashrc
個人:~/.bashrc
功能:
(1)定義命令別名和函數
(2)定義本地變量
編輯配置文件生效的兩種方法:
(1)重新啟動shell進程
(2).或source
bash退出任務:
.bash_logout shell退出時會自動執行的操作
用於:
(1)創建自動備份
(2)清除臨時文件
$-變量
$_:表示上一個命令的最後一個參數
$-:表示各種符號的組合,每個符號代表特定含義
echo $- 會顯示himBH,如果要去掉某一個選項使用 set + 後面跟要去掉的選項
h:hashall,打開這個選項後,shell會將命令所在的路徑hash下來;
i:判斷當前shell是否為交互式shell,如果為交互式shell,是擁有i這個選項的,非交互式則沒有
m:監控模式,前後臺切換
B:大括號擴展可用,echo {1..10}
H:歷史,可以列出歷史命令中的列表,還可以是用!代表前面的命令
Linux腳本基礎