bash基礎及shell編程初步
bash的特性及bash腳本編程初步
操作系統硬件, 內核把底層硬件的復雜性給隱藏起來,統一輸出為一種系統調用,系統調用非常底層,把系統調用封裝成了庫。讓程序運行起來。用戶在創建時有一個默認shell。終點設備用來當做標準輸入和輸出。
要想與主機交互,需要一個【終端】,附著在終端接口程序: CUI:KDE,GNome,XFce CLI:/etc/shells bash zsh fish
接口和計算機打交道非常重要
bash的特性: 命令行展開:~,{} 命令別名:alias,unalias 命令歷史:history 文件名通配:glob 快捷鍵:ctrl+a,e,u,k,l 命令補全:$PATH 路徑補全:用戶指定的起始位置下查找的
bash特性之:命令hash
緩存此前命令的查找結果:key-value(見直數據) key:搜索鍵 value:值 hash命令: hash:列出 hash -d COMMAND:刪除 hash -r :清空
bash的特征之:變量
程序:指令+數據
指令:由程序文件提供;
數據:可以通過標準輸入IO設備、文件、管道、變量(讀出的數據加工很多遍) 不會對源文件進行修改。文件,程序在CPU上運行,只能通過內存不斷加載指令,并對數據完成加工操作。從文件中copy一行出來,暫存在內存中某個位置,內存中指定位置的數據,由cpu運行的指令,完成字符改寫。改完后保存在內存中的另外一個位置。保存后輸出到IO設備上。接下來第二行數據讀出來,還保存在同樣的內存空間中,內存上的數據要不斷變化,將來cpu上的指令要不斷的引用這段內存上的數據。為了便于引用這段內存上的數據,取個名字叫變量。變量名稱是指向一個內存空間的,這個變量的名稱會不斷地發生變化,這就叫變量。
一個名字引用所有變量的值:數組。就是在一個大的內存空間中取一個名,其內部又被分成每一個邏輯單元,一個邏輯單元叫一個元素。同類元素,取同一個名稱,保存到一個內存空間中,叫數組。
數組也是變量,是一串連續的變量。
程序:算法+數據結構
算法:解決問題的路徑,過程需要依賴
變量名+指向的內存空間
變量名:指向內存空間中的某一空間的起止地址,在那一段空間中,我們就可以存儲數據
變量賦值:把我們要存儲的數據,存儲到變量名所指向的內存空間的過程。
shell變量賦值的方式:name=value 名稱=值 字符串存到了名稱所指向的內存空間中去了
變量類型:存儲格式、表示數據范圍、參與的運算
變量值的存儲類型;
字符串相加123,34 =12334 數值相加123,34=157
編程語言:
強類型變量:c
弱類型變量:bash把所有變量統統視作字符型;
bash中的變量無需事先聲明;相當于把聲明和賦值過程同時實現 聲明:類型,變量名 num1=123,str1=34 強類型中不被允許
弱類型:自動把字符串轉換成數值,或者反過來
變量替換:把變量名出現的位置替換為其所指向的內存空間中的數據;
變量引用:把變量名出現的位置替換${varname},$varname
特性:1、把所有變量都視作字符型 2、bash中的變量無需事先聲明,直接使用
變量名:變量名只能包含數字、字母和下劃線,不能以數字開頭; 變量名:見名知義,命名機制遵循某種法則;不能使用程序的保留字,例如if,else,then,while bash變量類型:
根據作用范圍劃分: 本地變量:作用域僅為當前shall進程 環境變量:作用域當前shell進程及子進程,同級沒影響 局部變量:作用域僅為某代碼片段(函數上下文)
linux是一個多用戶的操作系統,系統運行時多個用戶登錄進來,每個用戶都需要一個終端,每一個終端上就應該有一個接口,接口程序中最常見的就是CLI接口,CLI接口對應的就是shell進程,事實上默認的bash在用戶一登錄,我們系統就啟動一個bash進程來隨時響應用戶的請求。命令提示符信息就是又一個shell的進程顯示的,多個用戶登錄就意味著多個shell進程。shell進程之間是各自獨立的,每一個shell進程都有生命周期,各自獨立的概念,同級shell。在一個shell進程下,可以嵌套一個shell進程,shell類型也可以不一樣
位置參數變量:向執行腳本的shell進程傳遞的參數 特殊變量:shell內置的有特殊功能的變量: $?:上一個命令的執行狀態結果保存在特殊變量中 0:成功 1-255:失敗
定義方式
本地變量: 變量賦值:name=value 變量引用:${name},$name '',變量名不會替換為其值 "",變量名會替換為其值
查看變量:set 撤銷變量:unset name(變量名) 注意:此處非變量引用,不能使用$ 環境變量: 變量賦值: (1) export name=value (2) name=value export name (3) declare -x name=value (4) name=value declare -x name 變量引用:$(name),$name 注意:bash內嵌了許多環境變量(通常為全大寫字符),用于定義bash的工作環境 PATH,HISTFILE,HISTSIZE,HISTFILESIZE,HISTCONTROL,PWD,UID,HOME,SHELL,OLDPWD 查看環境變量:export,declare -x,printenv,env 撤銷環境變量:unset name 注意:只加name,不加$
只讀變量:不能修改和不能取消 (1)declare -r name (2)readonly name
只讀變量無法重新賦值,并且不支持撤銷;存活時間為當前shell進程的生命周期,隨shell進程的終止而終止
bash特性之多命令執行: ~]# COMMAND1;COMMAND2;COMMAND3; 一行多個命令
邏輯運算: 運算數:真(true,yes,on,1) 假(false,no,off,0) 與: 1 && 1=1 1 && 0=0 0 && 1=0 0 && 0=0 或: 1 || 0 =1 1 || 1 =1 0 || 1 =1 0 || 0 =0 非: ! 1 =0 ! 0 =1 短路法則: ~]# COMMAND1 && COMMAND 兩個命令的執行狀態結果做出&運算 COMMAND1為假,則COMMAND2不會再執行; 否則:COMMAND1為真,則COMMAND2必須執行; ~]# COMMAND1 || COMMAND2 COMMAND1為真,則COMMAND2不會再執行; 否則:COMMAND1為假,則COMMAND2必須執行; ~]# id $username || useradd $username
shell腳本編程: 編程語言的分類:根據運行方式 編譯運行:源代碼–>編譯器(編譯)–>程序文件 然后運行程序文件(運行速度更快,需要先編譯,有bug,先修改源代碼,再編譯,才能運行。后來出現了項目管理工具,能夠將一個源代碼文件切割成放置在n個文件中,導致某一個文件可以獨立編譯,單獨編譯錯誤的地方) c語言:所寫出來的源代碼,編程成指定的二進制文件也有可能是庫文件,調用函數庫的函數來實現獨立完成,無需調用外部的其他程序
解釋運行:源代碼-->運行時啟動解釋器,由解釋器邊解釋邊運行;源代碼本身并不運行,運行一個解釋器進程,把源代碼的內容當作解釋器要運行的程序。解釋運行 萬一發現錯誤,僅需要修改源代碼,在進行解釋運行
都需要一個翻譯官
腳本編程是完全借助于外部的程序來完成 根據其編程過程中功能的實現是調用庫還是調用外部的程序文件: shell腳本編程: 利用系統上的命令及編程組件進行編程; 完整編程: 利用庫或編程組件進行編程 程序員不需要操作系統上必須存在某個命令,自己通過庫或者自己所寫的代碼來完成所有操作 根據編程模型分類 過程式編程語言: 面向對象的編程語言: 程序=指令+數據 過程式:以指令為中心來組織代碼,數據是服務于代碼; 順序執行 選擇執行 循環執行 過程式代表:c語言,bash 對象式:以數據為中心來組織代碼,圍繞指數據來組織指令; 類(class):實例化對象,method; 首先程序員要寫很多類,每一個類當中包含的數據結構或者稱實例化出來的數據對象,對這個對象要施加哪些操作, 對象式代表:java,c++,python shell腳本編程:過程式編程,解釋運行,依賴于外部程序文件運行;可以多個命令一遍運行出來。 如何寫shell腳本: 腳本文件的第一行,頂格:給樹shebang,解釋器路徑,用于指明解釋執行當前腳本的解釋器程序文件 常見的解釋器: #!/bin/bash #!/user/bin/python #!/user/bin/perl 文本編輯器:nano 行編輯器:sed 全屏幕編輯:nano,vi,vim shell腳本是什么? 命令的堆積; 但很多命令不具有冪等性,需要用程序邏輯來判斷運行條件是否滿足,以避免其運行中發生錯誤; 運行腳本: (1)賦予執行權限,并直接運行此程序文件; chmod+x /RATH/TO/SCRIPT_FILE ./PATH/TO/SCRIPT_FILE (2)直接運行解釋器,將腳本以命令行參數傳遞給解釋器程序 bash /PATH/TO/SCRIPT_FILE 注意:腳本中的空白行會被解釋器忽略 腳本中,除了shebang,余下所有以#開頭的行,都會被視作注釋行而被忽略;此即為注釋行; shell腳本的運行是通過運行一個子shell進程實現的
練習1:寫一個腳本,實現如下功能; (1)顯示/etc下目錄下所有以大寫p或小寫p開頭的文件或目錄本身 (2)顯示/var目錄下的所有文件或目錄本身,并將顯示結果中的小寫字母轉換為大寫后顯示; (3)創建臨時文件/tmp/mtfile.xxxx;
#!/bin/bash ls -d /etv/[pP]* ls -d /var/* |tr [a-z] [A-Z] mktemp /tmp/myfile.xxxx
bash的配置文件: 兩類: profile類:為交互式登錄的shell進程提供配置 bashrc類:為非交互式登錄的shell進程提供配置
登錄類型: 交互式登錄shell進程: 直接通過某終端輸入賬號和密碼后登錄打開的shell進程; 使用su命令:su -USERNAME,或者使用su- |username的登錄切換;
非交互式登錄shell進程; su username執行的登錄切換; 圖形界面下打開的終端; 運行腳本 profile類: 全局:對所有用戶都生效; /etc/profile /etc/profild.l/*.sh 用戶個人:僅對當前用戶有效; ~/.bash_profile 功用: 1、用于定義環境變量; 2、運行命令或腳本; bashre類: 全局: /etc/bashrc 用戶個人: ~/.bashrc 功用: 1、定義本地變量; 2、定義命令別名; 注意:僅管理員可修改全局配置文件; 交互式登錄shell進程: /etc/profile -->/etc/profile.d/* --> ~/.bash_profile -->~/.bashre -->etc/bashrc 非交互式登錄shell進程: ~/.bashrc -->etc/bashrc-->/etc/profile.d/* 命令行中定義的特性,例如變量和別名作用域為當前shell進程的生命周期; 配置文件定義的特性,只對隨后新啟動的shell進程有效; .命令 讓通過配置文件定義的特性立即生效: (1)通過命令行重新定義一次; (2)讓shell進程重讀配置文件; ~]#source /PATH/FROM/CONF_FILE ~]#./PATH/FRON/CONF_FILE
正則表達式與grep
回顧:hash、變量、shell的腳本編程 bash的特性:hash,變量 命令hash:此前查找的命令結果給緩存起來 ,并且再次執行時使得其執行性能更好。保存方式:hash命令
變量類型: 本地變量,環境變量,局部變量 位置參數變量,特殊變量 變量的賦值方式:name=value 環境變量使用:export name=value declare -x name =value 變量引用:$name,$(name) 撤銷:unset name
bash腳本編程的簡單實現,運行腳本 #!/bin/bash #開頭和空白行都會被忽略
bash的配置文件 profile類:登錄式shell
su – 終端
bashrc類:非登錄式shell 圖形界面下的窗口 登錄式shell:讀得次序 /etc/profile -->etc/profile.d/*.sh--> -/.bash_profile--> -/.bashrc -->/etc/bashrc 非登錄式shell:~/.bashrc -->etc/bashrc -->etc/profile.d/*.sh
profile類的配置文件主要是用來實現定義環境變量或定義運行的命令或腳本。 bashrc類的配置文件主要用來定義本地變量和命令別名
抽取文本的工具: 查看文件內存:cat -n:顯示行號,空行也加行號 -b:顯示行號,忽略空行 -ns:顯示行號,壓縮空行,相鄰的空行可以壓縮掉 -v:能看到^M -A:顯示所有
more:分頁查看文件 more [option..] FILE.. -d:顯示翻頁及退出提示 less:可以上下翻頁 搜索關鍵字 head: head [option]..[file..] -c #:指定獲取前#字節 -n #:指定獲取前#行 -#: 指定行 tail: tail [option]..[file].. -c #:指定獲取后#字節 -n #:指定獲取后#行 -#: -f:跟蹤顯示文件新追加的內容,常用日志監控 要求:自動顯示新日志,不影響日常工作 tail -n 0 -f /var/log/messages &
按列抽取文本cut和合并文件paste cut [option] .. [file] … -d DELIMITER:指明分隔符,默認tob -f FILEDS: 例如cut -d: -f1,2,3 文件名 #:第#個字段 #,#[,#]:離散的多個字段,例如1,3,6 #-#:連續的多個字段,例如1-6 混合使用:1-3,7 -c :按字符切割 –output-delimiter=STRING指定輸出分隔符 例如cut -d:f1,3 –output-delimiter=" " 文件名
顯示文件或STDIN數據的指定列 cut -d:-f1 /etc/passwd cat /etc/passwd | cut -d : -f7 cut -c2-5 /usr/share/dict/words paste [option]..[file].. -d 分隔符:指定分隔符,默認用TAB -s:所有行合成一行顯示 paste f1 f2 paste -s f1 f2
分析文本的工具 收集文本統計數據wc 計數單詞總數、行總數、字節總數和字符總數 可以對文件或STDIN中的數據預習 $ wc story/txt 39 237 1901 story.txt 行數 字數 字符數
使用 -l 來只計數行數 使用 -w 來只計數單詞總數 使用 -c 來只計數字節總數 使用 -m 來只計數字符總數
文本排序sort 把整理過的文本顯示在STDOUT,不改變原始文件 $ sort [option] file(s)
常用選項 -r:執行反方向(由上至下)整理 -n:執行按數字大小整理 -f:選項忽略(fold)字符串中的字符大小寫 -u:選項(獨特,unique)刪除輸出中的重復行 -t c :選項使用c做為字段界定符 -k X :選項按照使用c字符分隔的X列來整理能夠使用多次 例如:sort -t: -k2 -n 以冒號為分隔符,第二列,按數字大小排序
文本處理工具:
linux上文本處理三劍客: grep:文本過濾工具(模式:pattern)工具; grep:基本正則表達式,-E支持擴展正則表達式 egrep:支持擴展正則表達式,-G表示支持基本正則表達式 fgrep:不支持正則表達式,-E擴展,-G基本 sed:stream editor,流編輯器;文本編輯工具; awk:linux上的實現為gawk,文本報告生成器(格式化文本);
重點中的重點: 正則表達式:Regual Expression ,簡寫REGEXP 由一類特殊字符及文本字符所編寫的模式,其中有些字符不表示其字面意義,而是用于表示控制或通配的功能; 分兩類: 基本正則表達式:BRE 擴展正則表達式:ERE
元字符:正則表達式的元字符 匹配單詞\(hello[[:space:]]\+\)\+ 都有特殊的功用和意義
之所以計算機有只能功能,正則表達式的出現立下汗馬功勞,因為正則表達式能分析目錄并查找符合條件的文本。 計算機中的數據,文本數據,數字數據。處理工具智能化。
grep工具: global search regular expression and print out the line 會全文搜索每一行,根據用戶所給定的格式來過濾,再每一行執行相應的解鎖工作,如果某一行能被模式匹配到,則把這一行顯示出來 作用:文本搜索工具,根據用戶指定的“模式(過濾條件)”對目標文本進行匹配檢查;打印匹配到的行; 模式:由正則表達式的元字符及文本字符編寫出的過濾條件; 每一個正則表達式模式的實現或者稱能夠搜索正則表達式模式 的實現都要用到正則表達式引擎; 正則表達式引擎: grep [options] PATERN [FILE..] grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...]
例如:grep "UUID" /etc/fstab OPTIIONS: –color=auto;對匹配到的文本做著色后高亮顯示; -i:ignorecase;忽略字符大寫小寫; -o:僅顯示匹配到的字符串本身; -v:反向匹配;顯示不能被模式匹配到的行; -E:支持使用擴展的正則表達式元字符; -q:–quiet,–silent:靜默模式,即不輸出任何信息;
-A #:after,后#行 -B #:before,前#行 -C #:context,前后各#行 基本正則表達式的元字符: 字符匹配: . :匹配任意單個字符 grep "r..t" /etc/fstab [] :匹配指定范圍內的任意單個字符 grep "r[[:alpha:]][[:alpha:]]t" /etc/fstab [^] :匹配指定范圍外的任意單個字符; [:digit:],[:lower:],[:upper:],[:alpha:],[:alnum:],[:punct:],[:space:] grep "roo[[:digit:]]" /ets/fstab 匹配次數:用在要指定其出現的次數的字符的后面,用于限制其前面字符出現的次數;默認工作于貪婪模式; *:匹配其前面的字符任意次;0,1,多次; 例如:grep "x"*"y" .*:匹配任意長度的任意字符 \?:匹配前面的字符0或1次;即其前面的字符是可有可無的; \+:匹配其前面的字符1次或多次;及其前面的字符至少要出現一次; \{m\}:匹配其前面的字符m次; \{m,n}:匹配其前面的字符至少m次,至多n次 \{0,n\}:至多n次 \{m,\}:至少m次 位置錨定:用元字符要加引號 ^:行首錨定:用于模式的最左側;^root $:行尾錨定:用于模式的最右側; ^PATTERN$:用PATTERN來匹配整行;PATTERN開頭和結尾的行 ^$:空白行; ^[[:space:]]*$:空行或包含空白字符的行; 單詞:非特殊字符組成的連續字符(字符串)都稱為單詞; \<或\b:詞首錨定,用于單詞模式的左側; grep "\<root" /etc/fstab \>或\b:詞尾錨定,用于單詞模式的右側; \<PATTERN\>:匹配完整單詞; 練習: 1、顯示/etc/passwd文件中不以/bin/bash結尾的行; 2、找出/etc/passwd文件中兩位數或三位數; 3、找出/etc/rc.d/rc.sysinit或etc/grub2.cfg文件中,以至少一個空白字符開頭,且后面非空白字符的行; 4、找出"netstat-tan"命令的結果中以'LISTEN'后跟空白字符結尾的行; 1、 grep -v "\(/bin/bash\)$" /etc/passwd 2、grep "\<[0-9]\{2,3\}\>"etc/passwd 3、grep "^[[:space:]]\+[^[:space:]]" /etc/grub2.cfg 4、netstat-tan |grep "LISTEN[[:space:]]*$"
重點: 分組及引用 ():將一個或多個字符捆綁在一起,當做一個整體進行處理; (xy)*ab 把xy當做一個整體
注意:分組括號中的模式匹配到的內容會被正則表達式引擎自動記錄于內部的變量中,這些變量為: \1:模式從左側起,第一個左括號以及與之匹配的右括號之間的模式所匹配到的字符; \2:模式從左側起,第二個左括號以及與之匹配的右括號之間的模式所匹配到的字符; \3:,,, he likes his lover he loves his lover he likes his liker he loves his liker grep "\(l..e\).*\1" lovers.txt 后向引用:引用前面的分組括號中的模式所匹配到的字符;
正則表達式與grep
egrep: 支持擴展的正則表達式實現類似于grep文本過濾功能:grep -E
egrep [options] PATERN [FILE..] 選項: -i,-o,-v,-q,-A,-B,-C -G:支持基本正則表達式
擴展正則表達式的元字符: 字符匹配: .:任意單個字符 []:指定范圍內的任意單個字符 [^]:指定范圍外的任意單個字符 次數匹配 *:任意次,0,1或多次; ?:0次或1次,其前的字符可有可無的; +:其前字符至少1次; {m}:其前的字符m次; {m,n}至少m次,至多n次; {0,n}:最多n次 {m}:最少m次 位置錨定 ^:行首錨定 $:行尾錨定 \<,\b:詞首錨定 \>,\b:詞尾錨定 分組及引用 ():分組;括號內的模式匹配到字符會被記錄于正則表達式引擎的內部變量中; 后向引用:\1,\2... 注意:只能在正則表達式中引用這些變量的值,不能在bash中引用 或: a|b:a或者b; C|cat:C或cat (c|C):cat或Cat 練習: 1、找出/proc/meminfo文件中,所有以大寫或小寫s開頭的行;至少有三種實現方式; 2、顯示當前系統上root、centos或者user1用戶的相關信息; 3、找出/etc/rc.d/init.d/functions文件中某單詞后面跟一個小括號的行; 4、使用echo命令輸出一絕對路徑,使用egrep取出基名;取出其路徑名 5、找出ifconfig命令結果中的1-255之間的 數值; 6、找出ifconfig命令 7、添加用戶bash,testbash,basher以及nologin(其shell為sbin/nologin);而后找出/etc/passwd文件中用戶名同shell名的行;
1、grep -i "^s" /proc/meminfo grep "^[sS]" /proc/meminfo grep -E "^(s|S)" /proc/meminfo
2、grep -E "^(root|centos|user1)>" /etc/passwd 3、grep -E -o "[_[:alnum:]]+()" /etc/rc/d/init.d/ 4、 echo /etc/sysconfig/ |grep -E -o "[^/]+/?" 5、ifconfig | grep -E -o "\<([1-9]|[1-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])>" 6 7、grep -E "^([^:]+>).*\1$" /etc/passwd
fgrep:不支持正則表達式元字符: 當無需用到元字符去編寫模式時,使用fgrep必能更好;
文本查看及處理工具:wc,cut,sort,uniq,diff,patch
wc:word count 單詞統計 wc [option]..[FILE].. -l:line -w:word -c:bytes cut:從每一行中移除片段 cut:option..[file] option: -d CHAR:以指定的字符為分隔符; -f FIELDS:挑選出的字段; #:指定的單個字段; #-#:連續的多個字段; #,#:離散的多個字段; sort: sort [option]..[file].. -n:給予數值大小而非字符進行排序; -t CHAR:指定分隔符; -k#:用于排序比較的字段; -r:逆序排序; -f:忽略字符大小寫; -u:重復的行只保留一份; 重復行:連續且相同 uniq:報告或移除重復的行 -c:顯示每行的重復次數; -u:僅顯示未曾重復過的行; -d:僅顯示重復過的行; diff:逐行比較文件中的內容 diff [option]..FILES diff /PATH/TO/OLDFILE /PATH/TO/NEWFILE > /PATH/TO/PATCH_FILE -u:使用unfied機制,即顯示要修改的行的上下文,默認為3行; patch:向文件打不掉 patch[options] -i /PATH/TO/PATCH_FILE /PATH/TO/OLDFILE patch /PATH/TO/OLDFILE < /PATH/TO/PATCH_FILE
原創文章,作者:15152188070,如若轉載,請注明出處:http://www.www58058.com/30302