Linux學習第九節課-shell腳本編程
--------------------------------------------------------------------------------------------------------------------------------
程序:算法+數據結構
數據:程序的核心
算法:處理數據的方式
程序編程風格
過程式:以指令為中心,數據服務於指令
對象式:以數據為中心,指令服務於數據
高級編程語言
編譯:高級語言→編譯器→機器代碼→執行,例如c,c++等
解釋:高級語言→執行→解釋器→機器代碼,例如shell,python,php,javascript,perl等
編程邏輯處理方式
順序執行、循環執行、選擇執行
Shell腳本:包含一些命令或者聲明,並符合一定格式的文本文件
格式要求:#!/bin/bash(或者其他類型的shell文件,根據使用的shell類型進行選擇)
Shell腳本用途
自動化常用命令
執行系統管理和故障排除
創建簡單的應用程序
處理文本或文件
編寫完一個腳本後,使用chmoda+x給其執行權限,然後將腳本放入bash文件夾內或者更改$PATH或者輸入絕對/相對路徑來執行,寫的腳本屬於外部命令
變量
強類型:變量不經過強制轉換,它永遠是這個數據類型,不允許隱式的類型轉換。一般定義變量時必須指定類型、參與運算必須符合類型要求;調用未聲明變量會產生錯誤
如java,c#
弱類型:語言的運行時會隱式做數據類型轉換。無須指定類型,默認均為字符型;參與運算會自動進行隱式類型轉換;變量無須事先定義可直接調用如:bash不支持浮點數,php
變量命名法則:
1、不能使程序中的保留字:例如if,for
2、只能使用數字、字母及下劃線,且不能以數字開頭
3、見名知義
4、統一命名規則:駝峰命名法,例如小駝峰:studentName,大駝峰StudentName
局部變量:變量只能在當前進程使用,不可以給父進程或者子進程使用,name=“a”
環境變量:全局變量,生效範圍為其自身和其子進程,不能給父進程使用,exportname=”a”
本地變量:生效範圍為當前shell進程中某代碼片斷,通常指函數
位置變量:$1,$2,...來表示,用於讓腳本在腳本代碼中調用通過命令行傳遞給它的參數
特殊變量:$?,$0,$*,$@,$#,$$
$?判斷前一個命令成功還是失敗,沒有特別指定下,0為成功,1-255為失敗
$0腳本名
$*所有參數,參數是一個獨立的整體
$@所有參數,參數是獨立的個體
$#參數個數
$數字第數字個參數
$@$*只在被雙引號包起來的時候才會有差異
Shift:shift鍵1次後,第一個參數將沒有,之前第二個參數變為第一個參數,第n個參數變為第n-1個參數
$$查看命令當前進程
$PPID查看當前進程的父進程
啟用命令source、.和bash之間的區別
Source/.運行腳本不開啟子進程,會影響變量,而bash開啟子進程,不會影響變量,所有一般使用bash激活腳本,除非設備需要變化環境變量才會使用./source
變量賦值
變量賦值:name=‘value’,可以使用引用value:
(1)可以是直接字串;name=“root"
(2)變量引用:name="$USER"
(3)命令引用:name=`COMMAND`name=$(COMMAND)
變量引用:${name}$name
"":弱引用,其中的變量引用會被替換為變量值
'':強引用,其中的變量引用不會被替換為變量值,而保持原字符串
顯示已定義的所有變量:set
刪除變量:unsetname
顯示所有環境變量:
env
printenv
export
declare-x
只讀變量:只能聲明,但不能修改和刪除
聲明只讀變量:
readonlyname
declare-rname
查看只讀變量:readonly–p
位置變量:在腳本代碼中調用通過命令行傳遞給腳本的參數
set--清空所有位置變量
算術運算
bash中的算術運算:helplet
+,-,*,/,%取模(取余),**(乘方)
實現算術運算:
(1)letvar=算術表達式
(2)var=$[算術表達式]
(3)var=$((算術表達式))
(4)var=$(exprarg1arg2arg3...)
(5)declare–ivar=數值
(6)echo‘算術表達式’|bc
乘法符號有些場景中需要轉義,如*
bash有內建的隨機數生成器:$RANDOM(0-32767)
echo$[$RANDOM%50]:0-49之間隨機數
賦值
增強型賦值:
+=,-=,*=,/=,%=
letvarOPERvalue
例如:letcount+=3
自加3後自賦值
自增,自減:
letvar+=1
letvar++
letvar-=1
letvar—
邏輯運算
true, false
1, 0
與:
1 與 1 = 1
1 與 0 = 0
0 與 1 = 0
0 與 0 = 0
或:
1 或 1 = 1
1 或 0 = 1
0 或 1 = 1
0 或 0 = 0
非:!
! 1 = 0
! 0 = 1
短路運算
短路與
第一個為0,結果必定為0
第一個為1,第二個必須要參與運算
短路或
第一個為1,結果必定為1
第一個為0,第二個必須要參與運算
異或:^
異或的兩個值,相同為假,不同為真
條件測試
判斷某需求是否滿足,需要由測試機制來實現
專用的測試表達式需要由測試命令輔助完成測試過程
評估布爾聲明,以便用在條件性執行中
若真,則返回0
若假,則返回1
測試命令:
test EXPRESSION
[ EXPRESSION ]
[[ EXPRESSION ]]
註意:EXPRESSION前後必須有空白字符
根據退出狀態而定,命令可以有條件地運行
&& 代表條件性的AND THEN
|| 代表條件性的OR ELSE
test命令
長格式的例子:
test "$A" = "$B" && echo "Strings are equal"
test “$A”-eq “$B” && echo "Integers are equal"
簡寫格式的例子:
[ "$A" = "$B" ] && echo "Strings are equal"
[ "$A" -eq "$B" ] && echo "Integers are equal"
bash的數值測試
-v VAR
變量VAR是否設置
數值測試:
-gt 是否大於
-ge 是否大於等於
-eq 是否等於
-ne 是否不等於
-lt 是否小於
-le 是否小於等於
bash的字符串測試
字符串測試:
= 是否等於
> ascii碼是否大於ascii碼
< 是否小於
!= 是否不等於
=~ 左側字符串是否能夠被右側的PATTERN所匹配
註意: 此表達式一般用於[[ ]]中;擴展的正則表達式
-z "STRING“ 字符串是否為空,空為真,不空為假
-n "STRING“ 字符串是否不空,不空為真,空為假
註意:用於字符串比較時的用到的操作數都應該使用引號
Bash的文件測試
存在性測試
-a FILE:同-e
-e FILE: 文件存在性測試,存在為真,否則為假
存在性及類別測試
-b FILE:是否存在且為塊設備文件
-c FILE:是否存在且為字符設備文件
-d FILE:是否存在且為目錄文件
-f FILE:是否存在且為普通文件
-h FILE 或 -L FILE:存在且為符號鏈接文件
-p FILE:是否存在且為命名管道文件
-S FILE:是否存在且為套接字文件
文件權限測試:
-r FILE:是否存在且可讀
-w FILE: 是否存在且可寫
-x FILE: 是否存在且可執行
文件特殊權限測試:
-u FILE:是否存在且擁有suid權限
-g FILE:是否存在且擁有sgid權限
-k FILE:是否存在且擁有sticky權限
文件大小測試:
-s FILE: 是否存在且非空
文件是否打開:
-t fd: fd 文件描述符是否在某終端已經打開
-N FILE:文件自從上一次被讀取之後是否被修改過
-O FILE:當前有效用戶是否為文件屬主
-G FILE:當前有效用戶是否為文件屬組
雙目測試:
FILE1 -ef FILE2: FILE1是否是FILE2的硬鏈接
FILE1 -nt FILE2: FILE1是否新於FILE2(mtime)
FILE1 -ot FILE2: FILE1是否舊於FILE2
Bash的組合測試條件
第一種方式:
COMMAND1 && COMMAND2 並且
COMMAND1 || COMMAND2 或者
! COMMAND 非
如:[[ -r FILE ]] && [[ -w FILE ]]
第二種方式:
EXPRESSION1 -a EXPRESSION2 並且
EXPRESSION1 -o EXPRESSION2 或者
! EXPRESSION
必須使用測試命令進行
使用read來把輸入值分配給一個或多個shell變量
-p 指定要顯示的提示
-s 靜默輸入,一般用於密碼
-n N 指定輸入的字符長度N
-d ‘字符’ 輸入結束符
-t N TIMEOUT為N秒
read 從標準輸入中讀取值,給每個單詞分配一個變量
所有剩余單詞都被分配給最後一個變量
read -p “Enter a filename: “ FILE
把命令行分成單個命令詞
展開別名
展開大括號的聲明({})
展開波浪符聲明(~)
命令替換$() 和 ``)
再次把命令行分成命令詞
展開文件通配(*、?、[abc]等等)
準備I/0重導向(<、>)
運行命令
防止擴展
反斜線(\)會使隨後的字符按原意解釋
$ echo Your cost: \$5.00
Your cost: $5.00
加引號來防止擴展
單引號(’)防止所有擴展
雙引號(”)也防止所有擴展,但是以下情況例外:
?$(美元符號) - 變量擴展
?`(反引號) - 命令替換
?\(反斜線) - 禁止單個字符擴展
?!(嘆號) - 歷史命令替換
bash的配置文件
按生效範圍劃分,存在兩類:
全局配置:
/etc/profile
/etc/profile.d/*.sh
/etc/bashrc
個人配置:
~/.bash_profile
~/.bashrc
shell登錄兩種方式
交互式登錄:
(1)直接通過終端輸入賬號密碼登錄
(2)使用“su - UserName” 切換的用戶
執行順序:/etc/profile --> /etc/profile.d/*.sh --> ~/.bash_profile --> ~/.bashrc --> /etc/bashrc
非交互式登錄:
(1)su UserName
(2)圖形界面下打開的終端
(3)執行腳本
(4)任何其它的bash實例
執行順序: ~/.bashrc --> /etc/bashrc --> /etc/profile.d/*.sh
Profile類
按功能劃分,存在兩類:
profile類和bashrc類
profile類:為交互式登錄的shell提供配置
全局:/etc/profile, /etc/profile.d/*.sh
個人:~/.bash_profile
功用:
(1) 用於定義環境變量
(2) 運行命令或腳本
Bashrc類
bashrc類:為非交互式和交互式登錄的shell提供配置
全局:/etc/bashrc
個人:~/.bashrc
功用:
(1) 定義命令別名和函數
(2) 定義本地變量
編輯配置文件生效
修改profile和bashrc文件後需生效
兩種方法:
1重新啟動shell進程
2 . 或source
Bash 退出任務
保存在~/.bash_logout文件中(用戶)
在退出登錄shell時運行
用於
創建自動備份
清除臨時文件
$-變量
h:hashall,打開這個選項後,Shell 會將命令所在的路徑hash下來,避免每次都要查詢。通過set +h將h選項關閉
i:interactive-comments,包含這個選項說明當前的 shell 是一個交互式的 shell。所謂的交互式shell,在腳本中,i選項是關閉的。
m:monitor,打開監控模式,就可以通過Job control來控制進程的停止、繼續,後臺或者前臺執行等。
B:braceexpand,大括號擴展
H:history,H選項打開,可以展開歷史列表中的命令,可以通過!感嘆號來完成,例如“!!”返回上最近的一個歷史命令,“!n”返回第 n 個歷史命令
Linux學習第九節課-shell腳本編程