shell編程基礎

Shell編程課堂筆記php

目錄前端

Shell編程課堂筆記.............................................................................................................................................. 1java

shell編程第一天.................................................................................................................................................... 3node

一.爲何要學習Shell編程..................................................................................................................... 3mysql

二.什麼是shell.............................................................................................................................................. 4linux

三.什麼是Shell腳本................................................................................................................................... 4nginx

四.腳本語言的種類..................................................................................................................................... 6web

五.shell腳本的執行..................................................................................................................................... 8正則表達式

六.shell腳本開發級別規範及習慣......................................................................................................... 8sql

Shell編程次日................................................................................................................................................... 9

一. bash shell特性...................................................................................................................................... 9

二. 變量常見類型........................................................................................................................................ 9

三. 變量賦值方式..................................................................................................................................... 11

四. 變量數值運算..................................................................................................................................... 12

shell編程第三天................................................................................................................................................. 14

一.shell條件測試....................................................................................................................................... 14

shell編程第四天........................................................................................................................................ 21

二.shell流程控制....................................................................................................................................... 21

四.實例.安裝nginx.................................................................................................................................... 22

五. 根據不一樣的系統安裝不一樣的yum源.......................................................................................... 23

六. 安裝不一樣版本的PHP....................................................................................................................... 24

七. 流程控制語句case........................................................................................................................... 25

八. 實現簡單的JumpServer................................................................................................................. 27

九. 使用case實現多級菜單................................................................................................................. 29

十. expect進行參數傳遞,執行命令或其餘操做......................................................................... 30

十一. 批量獲取在線主機, 進行祕鑰批量分發............................................................................... 30

Shell編程第五天................................................................................................................................................. 33

一.for循環語句.......................................................................................................................................... 34

二. while循環語句.................................................................................................................................... 35

三. 監控網站,每隔10秒肯定一次網站是否正常...................................................................... 36

四. Shell內置命令..................................................................................................................................... 37

shell編程第六天................................................................................................................................................. 37

一. 回顧........................................................................................................................................................ 37

二. shell腳本之函數................................................................................................................................. 38

三. 函數變量做用域................................................................................................................................. 40

四. wgret命令參數,curl命令參數....................................................................................................... 40

shell編程第七天................................................................................................................................................. 41

一. shell數組應用...................................................................................................................................... 41

shell編程第八天................................................................................................................................................. 45

一.shell正則應用....................................................................................................................................... 45

二. 基礎正則表達式................................................................................................................................. 46

三. 擴展正則表達式................................................................................................................................. 47

四. 正則表達式實戰................................................................................................................................. 47

五. sed文本處理........................................................................................................................................ 48

六. sed匹配替換........................................................................................................................................ 51

七. awk文本處理....................................................................................................................................... 52

八. awk工做原理....................................................................................................................................... 53

九. awk模式動做....................................................................................................................................... 55

十. awk條件表達式.................................................................................................................................. 56

十一. 運算表達式..................................................................................................................................... 56

十二. 邏輯操做符和複合模式.............................................................................................................. 56

十三. Awk條件判斷................................................................................................................................. 57

十四. awk 循環語句................................................................................................................................. 58

十五. awk數組實戰.................................................................................................................................. 58

十六. Awk數組案例................................................................................................................................. 59

 


 

shell編程第一天

一.爲何要學習Shell編程

1.Shell腳本語言是實現linux/unix系統管理及自動化運維重要且必備的工具,linux/unix系統的底層及基礎應用軟件的核心大都涉及shell腳本內容.每個合格的linux系統管理員或運維工程師,都須要熟練shell腳本語言的編寫,並可以閱讀系統及各種軟件附帶的shell腳本內容,只有這樣才能提高運維人員的工做效率,適應日益複雜的工做環境,減小沒必要要的重複工做,從而爲我的的職場發展奠基較好的基礎

2.學好shell編程所需的基礎知識

  學好shell編程並設想輕鬆地經過shell腳本自動化管理企業生產系統的必備基礎以下:

  (1)對vim編輯器能熟練使用,熟練SSH終端機」.vimrc」等的配置

  (2)要有必定的linux命令基礎,至少掌握80個以上linux經常使用命令並能熟練使用

  (3)要熟練掌握linux正則表達式以及三劍客命令(grep ,sed,awk)

  (4)熟悉常見的linux網絡服務部署,優化,日誌分析及排錯

精簡系統啓動服務的方法

(1)setup  (2)ntsysv  (3)腳本

#!/bin/bash

for srv in `chkconfig  --list|grep 「3:on」|awk ‘{print $1}’`

do

   chkconfig $srv off

done

for srv  in crond network sshd rsyslog

do

   chkconfig  $srv  on

done

or

for Srv in `chkconfig --list | grep "3:on" | awk '{print $1}' | grep -vE "crond|network|sshd|rsyslog"`

do 

chkconfig $Srv off

done

3 如何才能學好Shell編程

學好Shell編程的核心:多練→多思考→再練→再思考,堅持如此循環便可!

學習的來源:

一、耳朵

二、眼睛

三、手

四、大腦

五、總結

(1)掌握Shell腳本的基本語法方法

(2)掌握Shell腳本的各類常見語法

(3)造成本身的腳本開發風格

(4)從簡單作起,簡單判斷,簡單循環

(5)多模仿、多離開參考資料練習、多思考

(6)學會分析問題,逐漸造成編程思惟

(7)編程變量名字規範,採用駝峯語法表示

(8)不要拿來主義,特別針對新手

二.什麼是shell

Shell是一個命令解釋權,它的做用是介紹執行用戶輸入的命令及程序等,用戶詩人一天命令,shell就解釋執行一條.這種從鍵盤一輸入命令,就能夠當即迴應的對話方式,備稱爲較好的方式

Shell存在於操做系統的最外層,負載直接與用戶對話,把用戶的輸入介紹給操做系統,並基礎各類各樣的操做系統的輸出結果,輸出到屏幕返回給用戶,當咱們輸入系統用戶名和密碼,登陸到linux後的全部操做都由shell解釋並執行

三.什麼是Shell腳本

系統目錄的堆積

特定的格式+特定的語法+系統的命令=文件

範例1:清除/var/log下messages日誌文件的簡單命令腳本

把全部命令放在一個文件裏堆積起來就造成腳本,下面就是一個由最簡單的命令堆積而成的shell腳本.要注意的是,得使用root身份來運行

#清除日誌腳本

cd  /varlog

cat  /devnull >messages

echo 「logs cleaned up」

提示: /varlog/messages是linux系統日誌文件很重要.

這個腳本實際上是有一些問題的,讀者有沒有看出來?它所在的問題以下:

 (1)若是不是root用戶,就沒法執行腳本清理日誌,而且會提示系統權限報錯.

 (2)沒有任何流程控制語句,簡單地說就是隻順序操做,沒有成功判斷和邏輯嚴密性.

範列2:寫一個包含命令,變量和流程控制語句的清除/var/log下messages日誌文件的shell腳本.

#/bin/bash

#清除日誌腳本

LOG_DIR=/varlog

#$uid爲0的用戶,即root用戶

ROOT_UID=0  

#腳本須要使用root用戶來運行,所以,對當前用戶進行判斷,不合要求的給出友好提示,並終止程序運行。

       if [ "$UID" -ne "$ROOT_UID" ] #若是當前用戶不是root,不容許執行腳本。

              then

              echo "Must be root to run this script." #給出提示後退出。

              exit 1 #<==退出腳本。

       fi

       #若是切換到指定目錄不成功,給出提示,並終止程序運行。

       cd $LOG_DIR || {

       echo "Cannot change to necessary directory."

       exit 1

       }

#通過上述兩個判斷後,此處的用戶權限和路徑就應該是對的,只有清空成功,纔打印成功提示.

       cat /dev/null>messages && {

       echo "Logs cleaned up."

       exit 0  #退出以前返回0表示成功. 返回1表示失敗。

       }

       echo "Logs cleaned up fail."

       exit 1

初學者若是想快速掌握shell腳本的編寫方法,最有效的思路就是採用電子遊戲中過關的方式,好比範列2的腳本能夠分紅以下幾關來設計:

第一關,必須是root才能執行腳本,不然給出友好提示並終止腳本運行.

第二關,成功切換目錄(cd  /var/log),不然給出友好提示並終止腳本運行.

第三關,清理日誌( cat  /dev/null >messages),清理成功給出正確提示.

第四關,通關或失敗,給出相應提高(echo輸出).

Shell腳本在linux運維工做中的地位

  Shell腳本語言很擅長處理純文本類型的數據,而linux系統中幾乎全部的配置文件,日誌文件(如NFS,Rsyanc,Httpd,Nginx,LVS,MySQL),以及絕大多數的啓動文件讀書純文本類型的文件.天然學好shell腳本語言,就能夠利用它在linux系統中發貨巨大的做用.

1.自動化的完成基礎配置

  系統初始化操做,系統更新,內存調整,網絡時區,SSH優化

2.自動化安裝程序

  LNMP,LAMP,MySQL,Nginx,Redis

3自動化調整配置文件

  nginx.conf . my.cnf

4.自動化部署業務

  部署php,java秒級回退

5.自動化按期備份恢復

  MySQL全備 + 增量 + binlog + crond + shell腳本

6.自動化信息的採集

  Zabbix + shell:硬件,系統,服務,網絡,等等

7.自動化日誌分析 ELK

  取值->排序->去重->統計->分析

8.自動化擴容/縮容

  Zabbix + shell

  -擴容:監控服務器cup,如cpu負載持續80%+

   觸發動做(腳本)

  -腳本:

   調用api開通雲主機->初始化環境->加入集羣->對外提供

  -縮容:

  監控服務器CUP使用率20%->判斷有多高wed節點->判斷是否超過預設->縮減到對應的預設狀態->變動負載配置

四.腳本語言的種類

1.shell腳本語言的種類

[root@oldboy ~]# cat /etc/shells

/bin/sh      

/bin/bash    

/sbin/nologin

/bin/dash

/bin/tcsh

/bin/csh

bash特色:

 命令補全: tab

 命令別名: alias unalias

 命令修改

 命令歷史:history

問題:history查看命令歷史時,能夠帶上時間戳麼?

答: export HISTTIMEFORMAT="%F %T `whoami`

history

 

Linux系統中的主流shell是bash,bash是由bourne shell(sh)發展而來,單bash還包含了csh和ksh的特點.

2.其餘經常使用的腳本語言種類

 (1)PHP語言

    PHP是網頁程序語言.也是腳本語言.它是一款更專一於web頁面開發(前端展現)的語言.

例如:wordpress,dedecms,discus等著名開源產品都是用PHP語言開發的

 (2)Perl語言

    Perl腳本語言,比shell腳本語言強大不少,在2010年之前很流行,它的語法靈活,複雜,在實現不一樣的功能時能夠用多種不一樣的方式,缺點是不易讀,團隊協做困難.

 (3)Python語言

    Python是近幾年很是流行的語言,它不但能夠用於腳本程序開發,也能夠實現web頁面程序開發(例如:openstack,saltsack都是Python語言開發的),遊戲開發.大數據開發.移動端開發

(4)GO語言

  Go語言是谷歌推出的一種全新的編程語言,能夠在不損失應用程序性能的狀況降低低代碼的複雜性。

Go 同時具備兩種編譯器,一種是創建在GCC基礎上的Gccgo,另一種是分別針對64位x64和32位x86計算機的一套編譯器(6g和8g)。谷歌目前正在研發其對ARM芯片和Android設備的支持。

3.shell腳本語言與PHP/perl/Python語言的區別和優點

  Shell腳本語言的優點在於處理偏操做系統底層的業務.

例如:linux系統內部的不少應用,(有的是應用的一部分)都是使用shell腳本語言開發的,由於有1000多個linux系統命令爲他作支撐.特別是linux正則表達式及三劍客 grep awk sed 等命令..

 

對於一些常見的系統腳本,使用shell開發會更簡單快速,

例如:讓軟件一鍵自動化安裝,優化,監控報警腳本,軟件啓動腳本,日誌分析腳本,雖然PHP/Python語言也可以作到,可是考慮到掌握難度,開發效率,開發習慣等,他們可能就不如用shell腳本語言流行及有優點.對於一些常規的業務應用,使用shell更符合linux運維簡單,易用,高效的三大基本原則

 

PHP語言的優點在於小型網站系統和開發;Python語言的優點在於開發較複雜的運維工具軟件,,web界面的管理工具和web業務的開發.(例如:CMDB自動化運維平臺,跳板機,批量管理軟件saltstack.雲計算openstack軟件)等.咱們開發一個應用根據業務需求結合不一樣語言優點及自身擅長的語言來選擇,揚長避短,從而達到高效開發及同樣自身維護等目的.

面向過程: shell  建立一臺電腦

面向對象:Python組裝一臺電腦

4.經常使用操做系統默認的是shell

經過如下兩種方法能夠查看CentOS linux系統默認的shell

方法1:

[root@oldboy ~]# echo $SHELL

/bin/bash

方法2:

[root@oldboy ~]# grep root /etc/passwd

root:x:0:0:root:/root:/bin/bash

提示:結尾的/bin/bash就是用戶登陸後的Shell解釋器。  

5.shell腳本的規範

  (1)腳本放在統一目錄

   mkdir  -p  /server/seripts

  (2)推薦使用vim編輯器編輯腳本

  (3)以.sh爲擴展名

  (4)規範的shell腳本第一行會支持由那個程序(解釋器)來執行腳本中的內容

   #!/bin/bash 或  #!/bin/sh

  (5)開頭的’#!’稱爲幻數,在執行shell腳本的時候,內核會根據」#!」後的解釋器來肯定用那個程序解釋腳本中的內容.

注意:這一行必須在每一個腳本頂端的第一行,若是不是第一行則爲腳本註釋行

(6)腳本註釋

  在shell腳本中,跟在#後面的內容表示註釋.註釋部署不會被執行.僅給人看.註釋能夠自成一行,也能夠跟在命令後面,與命令同行.要養成寫註釋的習慣,方便本身與他人

  最好不用中文註釋,由於在不一樣字符集的系統中會出現亂碼

(7)CMD

  CMD是command的縮寫.即命令提示符(CMD),是在OS / 2 , Windows CE與Windows NT平臺爲基礎的操做系統(包括Windows 2000和XP中, Vista中,和Server 2003 )下的「MS-DOS 方式」。中文版Windows XP 中的命令提示符進一步提升了與DOS 下操做命令的兼容性,用戶能夠在命令提示符直接輸入中文調用文件。

  在9x系統下輸入command就能夠打開命令行.而在NT系統上能夠輸入cmd來打開,在windows2000後被cmd替代,利用CMD命令查詢系統的信息或者是判斷網絡的好壞

五.shell腳本的執行

Shell腳本是從上至下,從左至右依次執行每一行的命令及語句,即執行完了一個命令後再執行下一個命令,若是在shell腳本中遇到子腳本(即:腳本嵌套)時,就會先執行子腳本的內容,完成後再返回父腳本繼續執行父腳本內的後續命令及語句.

一般狀況下,當shell腳本執行時,會向系統內核請求啓動一個新的進程,以便在該進程中執行腳本命令以及子shell腳本.

Shell腳本的執行一般能夠採用如下幾種方式:

(1):bash  script-name或sh

(2):path/script-name或./script-name (必需要有執行權限)

(3):source script-name或.將腳本里的代碼調入到當前環境運行

(4):cat script-name |bash

(5):bash < script-name

六.shell腳本開發級別規範及習慣

Shell腳本開發規範習慣很是重要,雖然這些規範部署必需要遵照的,但有了好的規範和習慣,能夠大大提高開發效率,並下降後期對於腳本的維護成本.當多人協做開發時,你們有一個互相遵照的規範就顯得更重要.哪怕是一我的開發,最好也採起一套固定的規範,這樣腳本更易讀,易於後期維護,最主要的是要讓本身養成一個一出手就是專業和規範習慣.

注意:

(1)登陸shell

  /etc/profile是登陸shell啓動後運行的第一個啓動腳本

  它只爲登陸shell運行;非登入shelll不會引起這個腳本

  登入shell加載啓動腳本的順序爲:

  /etc/profile → /etc/profile.d → .bash_profile  → .bashrc  → /etc/bashrc

  每一個調用的腳本會依次撤銷前一個調用腳本中的改變

  在退出登入shell時,咱們還能夠執行某些任務,如建立自動備份,清除臨時文件

  把這些任務放在.bash_logout文件中

(2)非登陸shell

  非登入shell加載啓動腳本順序:

  .bash  → /etc/bashrc  →  /etc/profile.d

Shell編程次日

一. bash shell特性

1.命令補全和文件路徑補全,若是寫錯沒法補全.

table

2.命令歷史記錄功能

history

3.命令別名功能

  alias  unalias

4.經常使用快捷鍵

  Ctrl+u,k,a,e,l,c,z,d,w,r,y,

5.先後臺做業控制

  bg,  fg,  jobs,  screen

6.輸入輸出重定向

  >  ,>>  ,2>  ,2>>  ,&>  ,cat <

7.管道

   |

8.命令排序

  ; 沒有邏輯關係,不管分號前面的命令執行是否成功都執行後者

  &&  前面執行成功,則執行後者

  || 前面執行不成功,則執行後者

  rpm -a mysql &>/devnull && echo 「已安裝」 || echo 「未安裝」

9.shell通配符

  * 匹配任意多個字符

  ? 匹配任意一個字符

  [ ]匹配括號中任意一個字符 a-z, 0-9, A-Z

  ( )在子shell中執行(cd /boot;ls) (umask 077; touch  file1000)

  { }集合 touch file{1..100}

  \ 轉義符

10.echo輸出顏色,printf 格式化輸出文件

  echo -e 「\033[30m 黑色字 \033[0m」

  echo -e "\033[31m 紅色字 \033[0m"

  echo -e 「\033[32m 綠色字 \033[0m」

echo -e "\033[33m 黃色字 \033[0m"

echo -e "\033[34m 藍色字 \033[0m"

echo -e "\033[35m 紫色字 \033[0m"

echo -e "\033[36m 天藍字 \033[0m"

echo -e "\033[37m 白色字 \033[0m"

二. 變量常見類型

 

變量說明:用一個固定的字符串去表示不固定的內容

變量

常量

Shell變量以下幾類分爲

(1)自定義變量

(2)系統環境變量

(3)位置參數變量

(4)預先定義變量

1.自定義變量

  變量名=變量值, 步容許數字命名, 不能使用-命名

  默認只在當前環境生效

  使用export能夠在當前用戶的全部環境中生效

  將export定義變量寫入/etc/bashrc,對全部用戶永久生效

  將export定義變量寫入 .bashrc,支隊該用戶永久生效

(1)引用變量

  $變量名  或 ${變量名}

(2)查看變量

  echo  $變量名

  set 顯示全部變量,包括自定義變量和環境變量

(3)取消變量

  unset 變量名

  做用範圍:僅在當前shell中有效

2.系統環境變量

  (1)定義環境變量`export export 變量,將自定義變量轉換成環境變量`

  (2)引用環境變量`$變量名 或 ${變量名}`

  (3)查看環境變量`echo $變量名 env |grep Name`

  (4)取消環境變量`unset 變量名`

  (5)變量做用範圍`在當前shell和子shell有效

3.位置參數變量

  腳本參數傳參: $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10}

4.預先定義變量

  $0腳本文件名

  $* 全部的參數 「$*」顯示會不一樣

  $@全部的參數

  $# 參數的個數

  $$ 當前進程的PID

  $! 上一個後天進程的PID

  $? 上一個命令的返回值 0 表示成功

例子:

#1.判斷用戶是否爲root

if [ $UID -eq 0 ];then

echo 「continue」

else

   echo 「please change user」

   root

   exit

fi

#2.判斷軟件包是否安裝

rpm  -q  $1 &>/dev/null

if  [ $? -eq 0 ];then

   echo  「package  $1 installed」

else

echo 「package $1 not installed」

fi

ping $1 -c2 -f &> /dev/null                                                                              

if [ $? -eq 0 ];then

    echo "$1 up"

else

    echo "$1 down"

fi

三. 變量賦值方式

1.顯示賦值(變量名=變量值)

例:

ip1=192.168.56.11

school="Oldboyedu"

today1=`date +%F`

today2=$(date +%F)

//例:取根分區使用百分比

[root@oldgirl 02 12:16:28]# df -h|grep /$ | awk '{print $5}'

2%

[root@oldgirl 02 12:17:27]# df -h| awk 'NR==2{print $5}'

2%

[root@oldgirl 02 12:19:02]# echo `df -h| awk 'NR==2{print $5}'`

2%

[root@oldgirl 02 12:19:21]# echo $(df -h| awk 'NR==2{print $5}')

2%

2.read從鍵盤讀入變量值

  read -p 「提示信息:」 變量名

  read -t 5 -p "提示信息: " 變量名

[root@oldgirl 02 12:32:33]# read -p "input username,password: " User Pass

input username,password: aaa 123

[root@oldgirl 02 12:33:12]# echo $User

aaa

[root@oldgirl 02 12:33:18]# echo $Pass

123

3.注意事項: 定義或引用變量時注意事項: " "弱引用,' '強引用

[root@shell ~]# school=Iphone

[root@shell ~]# echo "${school} is good"

Iphone is good

[root@shell ~]# echo '${school} is good'

${school} is good

4.``命令替換等價於 $()反引號中的shell命令會被先執行

[root@shell ~]# touch `date +%F`_file1.txt

[root@shell ~]# touch $(date +%F)_file2.txt

[root@shell ~]# Root_Partition_Usage=$(df -Ph |grep '/$' |awk '{print $5}')

[root@shell ~]# Root_Partition_Usage=`df -Ph |grep '/$' |awk '{print $5}'`

 

四. 變量數值運算

1.從前日後輸出變量內容

[root@shell ~]# url=www.sina.com.cn

//獲取變量值的長度

[root@shell ~]# echo ${#url}

 

//從前日後,最短匹配

[root@shell ~]# echo ${url#*.}

 

//從前日後,最長匹配(貪婪匹配)

[root@shell ~]# echo ${url##*.}

2.從後往前刪除變量內容

[root@shell ~]# url=www.sina.com.cn

//從後往前,最短匹配

[root@shell ~]# echo ${url%.*}

//從後往前,最長匹配 貪婪匹配

[root@shell ~]# echo ${url%%.*}

3.索引及切片

//從0列開始,切出5列,第0-4列

[root@shell ~]# echo ${url:0:5}

//從5列開始,切出5列,第5-9列

[root@shell ~]# echo ${url:5:5}

//去除前5列

[root@shell ~]# echo ${url:5}

4.變量內容替換

[root@shell ~]# url=www.sina.com.cn

//將第一個匹配的sina替換爲baidu

[root@shell ~]# echo ${url/sina/baidu}

//將第一個匹配的n替換爲N

[root@shell ~]# echo ${url/n/N}

//貪婪匹配

[root@shell ~]# echo ${url//n/N}

5.變量替代

${變量名-新的變量值}

       變量沒有被賦值:會使用「新的變量值「 替代

       變量有被賦值(包括空值):不會被替代

       //例1

       [root@Shell ~]# url=www.sina.com

       [root@Shell ~]# echo $url

       www.sina.com

       [root@Shell ~]# echo ${url-www.baidu.com}

       www.sina.com

       [root@Shell ~]# unset url

       [root@Shell ~]# echo ${url-www.baidu.com}

       www.baidu.com

//例2

       [root@Shell ~]# url2=

       [root@Shell ~]# echo ${url2-www.baidu.com}

${變量名:-新的變量值}

變量沒有被賦值(包括空值): 都會使用「新的變量值「

替代

變量有被賦值: 不會被替代

//例1

[root@Shell ~]# unset url

[root@Shell ~]# echo $url

 

[root@Shell ~]# url=www.sina.com

[root@Shell ~]# echo $url

www.sina.com

[root@Shell ~]# echo ${url:-www.baidu.com}

www.sina.com

[root@Shell ~]# unset url

[root@Shell ~]# echo ${url:-www.baidu.com}

www.baidu.com

 

//例2

[root@Shell ~]# url2=

[root@Shell ~]# echo $url2

 

[root@Shell ~]# echo ${url2:-www.baidu.com}

www.baidu.com

6.變量自增

[root@shell ~]# unset i

[root@shell ~]# unset j

[root@shell ~]# i=1

[root@shell ~]# j=1

[root@shell ~]# let x=i++ 先賦值,再運算

[root@shell ~]# let y=++j 先運算,再賦值

 

//對變量值不會產生任何影響

[root@shell ~]# echo $i

2

[root@shell ~]# echo $j

2

 

//對錶達式的值的影響

[root@shell ~]# echo $x

1

[root@shell ~]# echo $y

2

 

對變量的值的影響:

[root@shell ~]# i=1

[root@shell ~]# let i++

[root@shell ~]# echo $i

2

shell編程第三天

一.shell條件測試

條件測試:

   判斷某需求是否知足,須要由測試機制來實現:

   如何編寫測試表達式實現所需的測試:

     (1)執行命令,並利用命令狀態返回值來判斷;

     (2)測試表達式

         Test expression

         [ expression ]

         [[ expression ]]

注意:expression兩端必須有空白字符,不然爲語法錯誤

   腳本的狀態返回值:

     默認是腳本中執行的最後一條命令的狀態返回值;

     自定義狀態退出狀態碼;

     注意shell檢查遇到exit時,即會終止,所以,整個腳本執行幾位結束;

1.文件測試

 存在性測試:

   -a file

   -e file

      文件的存在性測試,存在則爲真,不然則爲假;

 存在性及類型測試

   -b file: 塊

   -c file: 字符設備

   -d file: 目錄

   -f file:  普通文件

   -h file或-L file:符號鏈接

   -p file:命令管道

   -s file:套接字

 文件權限測試:

   -r. -w. -x :

   -u file:是否存在而且擁有suid權限

   -g file:是否存在而且擁有sgid權限

   -k file:是否存在而且擁有sticky權限

 文件是否有內容:

   -s  file:是否有內容,有爲真,沒有爲假;

 時間戳測試:

   -N fiel: 文件自從上一次讀操做後,是否被修改過;

 從屬關係測試;

   -O fiel:當前用戶是否爲文件屬主;

   -G fiel:當前用戶是否屬於文件的屬組;

 雙目測試:

   file1 -ef

   file2: file1與file2是否爲指向同一個文件系統上的相同inode的硬鏈接;

   file1 -nt  file2: file1是否新宇file2;

   file1 -ot  file2: fiel1是否舊於file2;

2.常見使用方式

 [ ! -d /bbb ] && mkdir /test

 [ -d /bbb ]  ||  mkdir  /test

3.腳本使用方式

#!/bin/bash

#定義備份目錄站點

back_dir=/var/mysql_back

 

#test -d $back_dir  || mkdir  -p $back_dir

if [ ! -d $back_dir ];then

   mkdir -p $dack_dir

fi

echo 「開始備份.....」

4.數值比較

數值比較 [ 整數1操做符 整數 2 ]

  -gt  大於

  -lt  小於

  -eq 等於

  -ne 不等於

  -ge 大於等於

  -le  小於等於

例:

1.條件測試, 腳本使用案例, 建立用戶

#!/bin/bash

read -p  「please input a username:」 user

id $user &>/devnull;then

if [ $? -eq 0 ];then

   echo 「user $user already exists」

else

   useradd $user

   if [ $? -eq 0 ];then

      echo 「$user is created」

   fi

fi

2.查看磁盤當前使用狀態,若是使用率超過百分之80%則報警發郵件

#查看磁盤使用率

df -h |grep 「/$」|awk ‘{print $5}’|awk -F ‘%’ ‘{print $1}’

#腳本

#!/bin/sbah

Root_Partition_Use=$(df -h|grep "/$"|awk '{print $5}'|awk -F '%' '{print $1}')

 

if [ $Root_Partition_Use -ge 30 ];then

    echo "root partition use:${Root_Partition_Use}%" > /tmp/disk_use.txt

fi

3.查看內存/當前使用狀態,若是使用率超過80%則報警發郵件

[root@shell]# cat mem_use.sh

Mem_Total=$(free -m|grep "^M"|awk '{print $2}')

Mem_Use=$(free -m|grep "^M"|awk '{print $3}')

Mem_Per=$((($Mem_Use*100)/$Mem_Total))

 

if [ $Mem_Per -ge 30 ];then

    echo -e "\033[31m Memory usage ${Mem_B}% is too high \033[0m"

else

    echo -e "\033[32m Memory usage ${Mem_B}% is normal \033[0m"

fi

5.字符串比較

字符串測試:字符比較

       ==:是否等於;

       >,<,!=

       =~:左側字符串是否可以被右側的PATTERN所匹配;

       -z "STRING":判斷指定的字符串是否爲空;空爲真,不空爲假;

       -n "STRING":判斷指定的字符串是否不空;不空爲真,空爲假;

 

       注意:

       (1)字符串要加引用;

       (2)要使用[[ ]];

(1)字符串比對

[root@shell]# [ "$USER " = "root" ];echo $?

0

[root@shell]# [ "$USER " == "root" ];echo $?

0

[root@shell]# BBB=""

[root@shell]# echo ${#BBB}

0

[root@shell]# [ -z "$BBB" ] 字符長度爲 0

[root@shell]# echo $?

0

[root@shell]# [ -n "$BBB" ] 字符長度不爲 0

[root@shell]# echo $?

1

//小結:變量爲空 或未定義: 長度都爲0

(2).字符串比對

[root@shell]# [ "$USER" = "root" ];echo $?

0

[root@shell]# [ "$USER" = "shell" ];echo $?

1

[root@shell]# [ "$USER" != "alice" ];echo $?

0

(3).多整數比對條件

[root@shell]# [ 1 -lt 2 -a 5 -gt 10 ];echo $?

1

[root@shell]# [ 1 -lt 2 -o 5 -gt 10 ];echo $?

0

[root@shell]# [[ 1 -lt 2 && 5 -gt 10 ]];echo $?

1

[root@shell]# [[ 1 -lt 2 || 5 -gt 10 ]];echo $?

0

6.正則比對

[root@shell]# [ "$USER" = "root" ];echo $?

0

[root@shell]# [ "$USER" =~ ^r ];echo $?

bash: [: =~: binary operator expected

2

[root@shell]# [[ "$USER" =~ ^r ]];echo $? //使用正則

0

//判斷變量是否是數字

[root@shell]# num=123

[root@shell]# [[ "$num10" =~ ^[0-9]+$ ]];echo $?

0

[root@shell]# [[ "$num20" =~ ^[0-9]+$ ]];echo $?

1

7.判斷用戶輸入的是不是數字

[root@shell]# cat test02.sh

#!/bin/bash

 

read -p "請輸入一個數值: " num

if [[ ! "$num" =~ ^[0-9]+$ ]];then

    echo " 你輸入的不是數字,程序退出!!!"

    exit

fi

echo "Number Is $num"

8. 批量建立用戶腳本, 僅我的使用

#!/usr/bin/bash

read -p "Please input number: " num

read -p "Please input prefix: " prefix

 

for i in `seq $num`

do

    user=$prefix$i

    useradd $user

    echo "123" |passwd --stdin $user &>/dev/null

    if [ $? -eq 0 ];then

        echo "$user is created."

    fi

done

9. 批量建立用戶腳本, 改進版

#!/usr/bin/bash

read -p "Please input number: " num

if [[ ! "$num" =~ ^[0-9]+$ ]];then

    echo "error number!" && exit 1

fi

 

read -p "Please input user prefix: " prefix

if [ -z "$prefix" ];then

    echo "error prefix"

    exit

fi

 

for i in `seq $num`

do

    user=$prefix$i

    useradd $user

    echo "123" |passwd --stdin $user &>/dev/null

    if [ $? -eq 0 ];then

        echo "$user is created."

    fi

done

企業案例1.輸入或經過命令行傳入一個字符或數字,若是傳入數字等於1,打印1;若是等於2,打印2;其餘值,提示輸入不對,退出

#echo -n "please input one key:"

#read value

read -p "please input one key:" value

[ ${#value} -ne 1 ] && {

    echo "please input one key"

    exit

}

expr $value + 1 &> /dev/null

[ $? -ne 0 ] && {

    echo "please input number"

    exit

}

[ $value -eq 1 ] && {

    echo $value

    exit 0

}

[ $value -eq 2 ] && {

    echo $value

    exit 0

}

[[ ! $value =~ [1-2] ]] && {

    echo "input error"

    exit 0

}

企業案例2.分別使用傳參和read讀入方式比較兩個整數大小,禁止使用if語句.

[ $# -ne 2 ] && {

    echo "please input two int."

    exit

}

int1=$1

int2=$2

expr $int1 + $int2 &> /dev/null

[ $? -ne 0 ] && {

    echo "please input int"

    exit

}

[ $int1 -gt $int2 ] && {

    echo "$int1 > $int2"

    exit

}

[ $int1 -lt $int2 ] && {

    echo "$int1 < $int2"

    exit

}

[ $int1 -eq $int2 ] && {

    echo "$int1 = $int2"

    exit

}

企業案例3.打印選擇菜單,按照選擇一鍵安裝不一樣的web服務。

       1.install lamp

       2.install lnmp

       3.exit

cat <<  End

    1.install lamp

    2.install lnmp

    3.exit

End

read -p "please input number you want:" num

expr $num + 1 &> /dev/null

[ $? -ne 0 ] && {

    echo "you input must be {1|2|3}."

    exit

}

[ $num -eq 1 ] && {

    echo "install lamp..."

#    source lamp_install.sh

    sleep 3

    exit $?

}

[ $num -eq 2 ] && {

    echo "install lnmp..."

#    source lnmp_install.sh

    sleep 3

    exit $?

}

[ $num -eq 3 ] && {

    echo "bye"

    exit $?

}

[[ ! $num =~ [1-3] ]] && {

    echo "input error"

    exit $?

}

shell編程第四天

一.回顧

1.條件判斷

test -d  filename

[ 2 -lt 3 ]

[[ 2 -lt 3 ]]

((2<3))

2.文件比較

文件類型

  -f

  -d

文件權限

2.數值比較

-le (小於等於)

-ge (大於等於)

-eq (等於)

-lt (小於)

-gt (大於)

-ne (不等於)

3.字符串比較

== (等於)

=~ (約等於)

!=  (不等於)

4.邏輯判斷

  && (前一個命令執行成功,再執行後一個命令)  字符 -a

  ||  (前一個美麗執行失敗,再執行後一個命令)   字符 -o

二.shell流程控制

1.流程控制語句if

單分支結構

 if [ 若是你有房 ];then

我就嫁給你

 fi

雙分支結構

 if [ 若是你有房 ];then

  我就嫁給你

 else

   再見

 fi

多分支結構

  if [ 若是你有房 ];then

   我就嫁給你

  elif [ 你有車 ];then

   我就嫁給你

  elif [ 你有錢 ];then

   我也嫁給你

  else

再見

 fi

 

猜數字遊戲,0-99之間數字

若是大了,就輸出一個信息.從新再猜

若是小了,就輸出一個信息,從新再猜

若是猜對了,恭喜,輸出猜的次數

腳本內容

#!/bin/bash

echo "下面咱們玩一個猜數字遊戲.取值範圍在0-99之間"

ran_num=$(expr $RANDOM % 100)

while true

do

    read -p "請輸入一個數字(0-99):" num

 

    [[ ! "$num" =~ ^[0-9]+$ ]] && {

    continue

}

    if [ $num -gt $ran_num ];then                                                                                                      

        echo "大了,請繼續:"

    elif [ $num -lt $ran_num ];then

        echo "小了,請繼續:"

    else

        echo "恭喜,你猜對了! $count"

        exit

    fi

done

四.實例.安裝nginx

#!/bin/bash

#install nginx

#1.判斷網絡

ping -c1 www.baidu.com $>/dev/null

if [ $? -ne 0 ];then

echo 「請檢查你的網絡」

exit 1

fi

#2.yum倉庫

yum_repo=$(yum repolist|grep nginx|wc -l)

if [ $yum_repo -eq 0 ];then

   cat >/etc/yum.repos.d/nginx.repo <<-EOF

   [nginx]

   name=nginx repo

   baseurl=http://nginx.org/packages/centos/7/x86_64/

   gpgcheck=0

   enabled=1

   EOF

   yum makecache

elif [ $yum_repo -eq 1 ];then

   yum install nginx -y  &>/dev/null

   install_nginx=$(rpm -q nginx|wc -l)

   if [ $install_nginx -eq 1 ];then

       echo 「 nginx已經安裝」

   fi

nginx_status=$(systemctl status nginx|grep Active |awk ‘{print $1 $3}’)

systemctl start nginx &>/dev/null

if [ $? -eq 0 ];then

  echo 「nginx 已經啓動完畢」

  echo 」nginx當前狀態是:$nginx_status」

else

  echo 「nginx啓動失敗 $nginx_status」

  killall  httpd  &>/dev/null

  killall  nginx  &>/dev/null

  systemctl start nginx

  if [ $? -eq 0 ];then

     echo -e 「nginx從新啓動成功」

     nginx_status=$(systemctl status nginx |grep Active |awk ‘{print $1 $3}’)

     echo  -e  「\033[32m $nginx_status \033[0m」

   fi

fi

else

echo 「未知問題,請手動檢查一下」

fi

五. 根據不一樣的系統安裝不一樣的yum源

#!/bin/bash

os_name=$(cat /etc/redhat-release)

os_version=$(cat /etc/redhat-release |awk ‘{print $4}’| awk -F ‘.’ ‘{print $1}’)

if [ $os_version = 「(Final)」 ];then

os_version=$(cat /etc/redhat-release |awk ‘{print $3}’ |awk -F ‘.’ ‘{print $1}’)

fi

if [ $os_vesion -eq 7 ];then

   mkdir -p /etc/yum.repos.d/backup

   mv /etc/yum.repos.d/* .repo /etc/yum.repos.d/backup

   cat >/etc/yum.repos.d/base.repo<<-EOF

   [base]

   name=local base yum source

   baseurl=ftp://192.168.56.1/base/7/x86_64

   enadle=1

   gpgcheck=0

   EOF

   Echo 「$os_name 系統已經配置好鬱悶倉庫」

elif [ $os_version -eq 6 ];then

    mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/backup

wget -o /etc/yum.repos.d/Centos-Base.repo

http://mirrors.aliyun.com/repo/Centos-6.repo

&>/dev/null

echo "$os_name 系統已經配置好yum倉庫"

elif [ $os_version -eq 5 ];then

mkdir -p /etc/yum.repos.d/backup

mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/backup

curl -o /etc/yum.repos.d/CentOS-Base.repo

http://mirrors.aliyun.com/repo/Centos-5.repo

&>/dev/null

echo "$os_name 系統已經配置好yum倉庫"

else

echo

"沒法檢測當前系統版本,請檢查/etc/redhat-release"

fi

 

六. 安裝不一樣版本的PHP

#!/bin/bash

#install php

install_php56() {

    echo "install php5.6......"

}

install_php70() {

    echo "install php7.0......"

}

install_php71() {

    echo "install php7.1......"

}

while :

do

    echo "################################"

echo -e "\t1 php-5.6"

echo -e "\t2 php-7.0"

echo -e "\t3 php-7.1"

echo -e "\tq exit"

echo "################################"

 

read -p "version[1-3]: " version

if [ "$version" = "1" ];then

    install_php56  

elif [ "$version" = "2" ];then

    install_php70

elif [ "$version" = "3" ];then

    install_php71

elif [ "$version" = "q" ];then

    exit

else

    echo "error"   

fi

done

七. 流程控制語句case

case語句

 

case 變量 in

模式 1)

    命令序列 1;;

模式 2)

    命令序列 2;;

模式 3)

    命令序列 3 ;;

*)

    無匹配後命令序列

Esac

1.批量刪除用戶

 

#!/bin/bash

read -p "Please enter the username prefix to be deleted: " delname

read -p "Please enter the number of users you need to delete:" delnum

 

echo "You want to delete the following users:

Username prefix: $delname

User number: $delnum

"

 

for i in $(seq $delnum)

do

    username=$delname$i

    read -p "are you sure you want to delete ${username}?[y|Y|Yes|n|N|NO] " reday

    case $reday in

        y|Y|YES)

            id $username &>/dev/null

            if [ $? -eq 0 ];then

                userdel $username &>/dev/null

                echo "$username deleted."

            else

                echo "$username not exist."

            fi

            ;;

        n|N|no|NO|No)

            continue

            ;;

        *)

            echo "you can only enter [y|Y|Yes|n|N|NO]"

    esac

done

2.系統管理工具箱

 

Command action

h 顯示命令幫助

f 顯示磁盤分區

d 顯示磁盤掛載

m 查看內存使用

u 查看系統負載

q 退出程序

 

#!/bin/bash

menu(){

    cat <<-EOF

    ===================

    h 顯示命令幫助   

    f 顯示磁盤分區

    d 顯示磁盤掛載

    m 查看內存使用

    u 查看系統負載

    q 退出程序

    =====================

EOF

}

menu

while true

do

    read -p "Command [h|f|d|m|u|q]: " sys

    case "$sys" in

        h)

            clear

            menu

            ;;

        f)

            clear

            lsblk

            ;;

        d)

            clear

            df -h

            ;;

        m)

            clear

            free -m

            ;;

        u)

            clear

            uptime

            ;;

        q)

            break

            ;;

        *)

            echo "you can olny enter [h|f|d|m|u|q]."

            continue

    esac

done

八. 實現簡單的JumpServer

#!/usr/bin/bash

 

#jumpServer

 

Mysql_master=192.168.70.160

Mysql_slave1=192.168.70.161

Mysql_slave2=192.168.70.162

Nginx_Up=192.168.70.150

Nginx_WEB1=192.168.70.151

Nginx_WEB2=192.168.56.11

 

menuinfo(){

        cat <<-EOF

        -------------------------------

        |       1) mysql-master         |

        |       2) mysql-slave1          |

        |       3) mysql-slave2          |

        |       4) Nginx-Upstream       |

        |       5) Nginx-WebNode1      |

        |       6) Nginx-WebNode2      |

        |       h) help                  |

        ---------------------------------

EOF

}

        #調用函數打印菜單

        menuinfo

        #控制不讓輸入ctrl+c,z

        trap "" HUP INT TSTP

while true

do

        read -p "請輸入要鏈接的主機編號: " num

        case $num in

                1|mysql-master)

                        ssh root@$Mysql_master

                        ;;

                2|Mysql_slave1)

                         ssh root@$Mysql_slave1

                        ;;

                3|Mysql_slave2)

                        ssh root@$Mysql_slave2

                        ;;

                h|help)

                        clear

                        meminfo

                        ;;

                #退出腳本後門, 不要讓其餘人知道

                exec)

                        break

                        ;;

        esac

done

//不管使用登錄式shell或非登錄式shell都會執行該腳本, 前提root用戶不容許登錄

[root@Shell day03]# cat /home/oldboy/.bashrc

sh /home/oldboy/jumpserver.sh

 

4.使用case編寫服務啓動與中止腳本

 

#!/usr/bin/bash

# manager Nginx start stop restart reload

source  /etc/init.d/functions

 

act=$1

te(){

if [ $? -eq 0 ];then

                action "Nginx Is $act" /bin/true

        else

                action "Nginx Is $act" /bin/false

fi

}

start(){

        /usr/sbin/nginx &>/dev/null

        te

 

}

stop(){

        /usr/sbin/nginx -s stop &>/dev/null

        te

}

 

reload(){

        /usr/sbin/nginx -s reload

        te

}

 

status(){

        Ngx_status=$(ps aux|grep "[n]ginx"|egrep -v "vi|sh"|grep master|awk '{print $2}')

        Nginx_Status_Port=$(netstat -lntp|grep nginx|awk '{print $4}')

        echo "Nginx_status_Pid: $Ngx_status"

        echo "Nginx_status_Port: $Nginx_Status_Port"

}

case $1 in

        start)

                start

                ;;

        stop)

                stop

                ;;

        restart)

                stop

                sleep 1

                start

                ;;

        reload)

                reload

                ;;

        status)

                status

                ;;

        *)

                echo "Usage: $0 {start|stop|status|restart|reload|}"

esac

九. 使用case實現多級菜單

## 3.交互腳本expect

1.expect實現簡單的交互登錄

 

#!/usr/bin/expect

spawn ssh root@192.168.70.161

 

expect {

    "yes/no" { send "yes\r"; exp_continue }

    "password:" { send "centos\r" };

}

interact

 

2.expect定義變量實現交互方式

 

#!/usr/bin/expect

set ip 192.168.70.161

set user root

set password centos

set timeout 5

 

spawn ssh $user@$ip

 

expect {

    "yes/no" { send "yes\r"; exp_continue }

    "password:" { send "$password\r" };

}

#交互方式

interact

十. expect進行參數傳遞,執行命令或其餘操做

#!/usr/bin/expect

#位置傳參

set ip [lindex $argv 0]

set user root

set password centos

set timeout 5

 

spawn ssh $user@$ip

 

expect {

    "yes/no" { send "yes\r"; exp_continue }

    "password:" { send "$password\r" };

}

 

#當出現#號符執行以下命令

expect "#"

send "useradd bgx\r"

send "pwd\r"

send "exit\r"

expect eof

十一. 批量獲取在線主機, 進行祕鑰批量分發

cat for_ip.sh

#!/usr/bin/bash

 

#1 拿到IP地址

>ip.txt

for i in {160..162}

do

        ip=192.168.70.$i

        {

        ping -c1 -W1 $ip &>/dev/null

        if [ $? -eq 0 ];then

                echo "$ip" >> ip.txt

        fi

        }&

done

#2.生成對應的密鑰

        if [ ! -f ~/.ssh/id_rsa ];then

                ssh-keygen -P "" -f ~/.ssh/id_rsa

        fi

 

#3.批量分發密鑰

        while read line

        do

                /usr/bin/expect <<-EOF

                        set pass 1

                        set timeout 2

                        spawn ssh-copy-id  $line -f

                        expect {

                                "yes/no" { send "yes\r"; exp_continue}

                                "password:" { send "1\r"}

                        }

                        expect eof

                EOF

        done<ip.txt

[root@oldboy 09]# cat rsyncd.sh

#!/bin/bash

##############################################################

# File Name: rsyncd.sh

# Version: V1.0

# Author: oldboy

# Organization: www.oldboyedu.com

##############################################################

RETVAL=0

start(){

    rsync --daemon

    RETVAL=$?

    if [ $RETVAL -eq 0 ]

    then

        echo "rsync is ok"

    else

        echo "rsync is fail"

    fi

}

stop(){

    killall rsync

    RETVAL=$?

    if [ $RETVAL -eq 0 ]

    then

        echo "rsync is stopped"

    else

        echo "rsync is stop fail"

    fi

}

case "$1" in

    start)

        start

        ;;

    stop)

        stop

        ;;

    restart)

        stop

        sleep 2

        start

        ;;

    *)

        echo "Usage:$0 {start|stop|restart}"

        exit 1

esac

專業一點的

[root@oldboy 09]# cat rsyncd2.sh

#!/bin/bash

# chkconfig: 2345 20 80

# description: rsync start and stop scripts

##############################################################

# File Name: rsyncd.sh

# Version: V1.0

# Author: oldboy

# Organization: www.oldboyedu.com

##############################################################

start(){

    rsync --daemon

    retval=$?

    if [ $retval -eq 0 ]

    then

        echo "rsync startup ok"

        return $retval

    else

        echo "rsync startup fail"

        return $retval

    fi

}

stop(){

    killall rsync

    retval=$?

    if [ $retval -eq 0 ]

    then

        echo "rsync stop ok"

        return $retval

    else

        echo "rsync stop fail"

        return $retval

    fi

}

case "$1" in

    start)

        start

        retval=$?

        ;;

    stop)

        stop

        retval=$?

        ;;

    restart)

        stop

        sleep 1

        start

        retval=$?

        ;;

    *)

        echo "usage:$0 {start|stop|restart}"

        exit 1

esac

exit $retval

 

Shell編程第五天

一.for循環語句

1.for 循環基礎語法

for 變量名 in [ 取值列表 ]

do

  循環體

done

2.for案例,批量探測主機存活狀態

#cat for_ip.sh

#循環主機

for i in {1..254}

do

  #併發執行

     {

      ip=10.0.0.$i

         ping  -c1 -W1 $ip &>/dev/null

         If [ $? -eq 0 ];then

            Echo 「$ip」 |tee -a  ip.txt

         fi

 }&

done

    #等待前臺進程結束,在日後執行

        wait

        echo "Get IP Is Finsh!!"

3.for循環批量建立用戶

#!/usr/bin/bash

 

read -p "請輸入用戶名前綴|密碼|數量: " rep pass num

 

if [[ ! $num =~ ^[0-9]+$ ]];then

        echo "Error 請從新輸入數字"

fi

 

cat <<-EOF

        你輸入的用戶名前綴是: $rep

        你輸入的統一密碼是: $pass

        你輸入要建立的數量: $num

EOF

        read -p "你肯定要建立嗎? [y|n]" aredy

        case $aredy in

               y|Y|yes|YES)

                   for i in $(seq $num)

                do

                       username=$rep$i

                    id $usernme &>/dev/null

                    if [ $? -ne 0 ];then

                           useradd $username && \

                           echo "$pass"|passwd --stdin $username &>/dev/null

                           echo "$username Is OK!"

                    fi

                         done

                  ;;

             n|N|No|NO)

                   exit 1

                  ;;

                           *)

                read -p "你肯定要建立嗎? [y|n]" aredy

        esac

4.for循環經過文件批量建立用戶

#!/bin/bash

 

for i in $(cat user.list)

do

       id $i &>/dev/null

    if [ $? -ne 0 ];then

           useradd $i && \

        echo "123" |passwd --stdin $i &>/dev/null

        echo "$i created."

    else

           echo "$i alreadt exists!!!"

    fi

done

 

5.批量修改密碼

 

#!/usr/bin/bash

for i in {160..162}

do

       ip=192.168.70.$i

    ping -c1 -W1 $ip &>/dev/null

    if [ $? -eq 0 ];then

           ssh $ip "echo 1|passwd --stdin root" &>/dev/null

        echo "$ip: Is Passwod Successfuly"

    fi

done

二. while循環語句

while循環基礎語法

//當條件測試成立(條件測試爲真),執行循環體

while 條件測試

do

循環體

done

1.使用while建立用戶

#!/usr/bin/bash

while read user

do

       id $user &>/dev/null

       if [ $? -eq 0 ];then

           echo "useradd $user is already exists"

    else

           useradd $user &>/dev/null

        echo "useradd  $user is Created."

    fi

done<user.list

#文件中存在用戶和密碼

#!/usr/bin/bash

while read user

do

        u=$(echo $user|awk '{print $1}')

        p=$(echo $user|awk '{print $2}')

 

        id $u &>/dev/null

        if [ $? -eq 0 ];then

                echo "useradd $u is already exists"

        else

                useradd $u &&\

                echo "$p"|passwd --stdin $u  &>/dev/null

                echo "useradd  $u is Created Passwd Is Ok."

        fi

 

done<user2.tt

三. 監控網站,每隔10秒肯定一次網站是否正常

#!/bin/bash

if [ $# -ne 1 ];then

       echo $"usage $0 url."

       exit1

fi

while true

do

       if [ $(curl -o /dev/null --connect-timeout 5 -s -w "%{http_code}" $1 | egrep -w "200|301|302" | wc -l) -ne 1 ];then

              echo "$1 is error."

       else

              echo "$1 is ok."

       fi

       sleep 10

done

四. Shell內置命令

exit 退出整個程序

break 結束當前循環,或跳出本層循環

continue 忽略本次循環剩餘的代碼,直接進行下一次循環

shell編程第六天

一. 回顧

day01:

1.shell腳本結構

  #!/bin/bash

cmd

2.shell腳本執行

bash/sh:不須要腳本具備執行權限,打開一個子進程使用bash來解釋腳本里面的語句.

./:(路徑)必需要有執行權限,打開一個字進程,使用bash來解釋腳本里面的語句.

source/. :不須要執行權限.直接將腳本里面的語句調入當前環境執行.

3.學習shell腳本的基礎:

  基礎命令

  如何更優秀:

  習慣

標準

day02:

1.變量類型

 自定義變量

    1.變量名必須用字母或_開頭

2.變量名=變量值,export , /etc/bashrc ,~/bashrc

 環境變量

1.變量名全大寫

2.變量名=變量值,export ,/etc/bashrc , ~/bashrc

 位置變量

$n

 預約義變量

$#   腳本里一共有幾個位置變量

$*   腳本里全部變量值  加」」會把全部變量值視爲一個總體

$@  腳本里全部變量值  加」」會把全部變量值單個顯示

$?   腳本里最後一個命令執行後狀態碼 0表示成功 非0表示不成功

$0   運行這個腳本的文件名

$!

$$

$_

day03:

1.條件測試語句

  test

  [ ]

  [[ ]] :字符串比較

  (( ))

day04:

1.判斷語句

 if 語句:

     單分支

     雙分支

     多分支

 case語句:

day05:

1.循環語句

  for

   while

 

二. shell腳本之函數

函數:function,把一段獨立功能的代碼看成一個總體,併爲之取一個名字,命名的代碼段,此即爲函數.

注意:定義函數的代碼段不會自動執行,在調用時執行;所謂調用函數,在代碼中給定函數名便可;函數名出如今任何位置,在代碼執行時,都會被自動替換爲函數代碼;

過程式編碼:代碼重用

模塊化編程

結構化編程

語法一:

   function f-name {

      ... 函數體...

}

語法二:(推薦)

f_name() {

   .....函數體....

}

例1:給定一個用戶名.取得用戶的id號和默認shell

  分析:

  1. 1.        grep  ^root /etc/passwd |awk  -F  ‘:’  {print $3,$7}
  2. 2.        grep  ^root /etc/passwd |  cut  -d:  -f3,7

例2:服務腳本框架

  分析:

  1. 1.        啓動

       返回值

       建立鎖文件

  1. 2.        關閉

       刪除鎖文件

  1. 3.        reload
  2. 4.        status
  3. 5.        usage
  4. 6.        chkconfig

函數的生命週期:

每次被調用時建立函數,返回時終止; 其狀態返回結果爲函數體中運行的最後一個命令的狀態;

自定義狀態返回值,須要使用」return」

   return [0-255]

   0:成功

   1-255:失敗

函數的執行結果返回值:

(1)      使用echo或printf命令進行輸出;

(2)      函數體中調用的命令執行結果;

函數的退出狀態碼:

(1)      默認取決於函數中執行的最後一條命令的退出狀態碼;

(2)      自定義:return

例1:添加10個用戶,用戶名做爲參數傳給函數

#!/bin/bash

#retval 0 :usrt  created

#retval 5 :user  exist

adduser()  {

   if  id   $1 &>/dev/null;then

     return 5

    else

     useradd $1

     return $?

   fi

}

for i in `seq 10`

do

username=$1$i

adduser $username

RETVAL=$?

if  [ $RETVAL -eq 5 ];then

    echo 「$username  exist.」

elif [ $RETVAL -eq 0 ];then

    echo 「$username created.」

else

    echo 「no reason,please check it yoursrlf.」

 fi

done

函數可接受參數:

  傳遞參數給函數:在函數體中,可使用$1,$2,....引用傳遞給函數的參數,還能夠在函數中使用$*或$@引用全部參數,$#引用傳遞的參數的個數:

  在調用函數時,在函數名後面以空白符分隔給定參數列表便可,例如:testfunc  arg1 arg2 arg3....

三. 函數變量做用域

1.局部變量:

做用域是函數的生命週期:在函數結束時被自動銷燬;

定義局部變量的方法:local  VARIABLE=VALUE

2.本地變量:

做用域是運行腳本的shell進程的生命週期;所以,其做用範圍爲當前shell腳本程序文件

示例:

#!/bin/bash

name=tom

setname(){

     local name=jerry

     ceho 「Function:$name」

}

setname

echo 「shell:$name」

四. wgret命令參數,curl命令參數

 

 

shell編程第七天

一. shell數組應用

1.數組分類

普通數組:只能用整數 做爲數組索引

關聯數組:可使用字符串 做爲數組索引

2.普通數組

(1)數組賦值方式 

針對每一個索引進行賦值

[root@oldboy ~]# array1[0]=pear

[root@oldboy ~]# array1[1]=apple

[root@oldboy ~]# array1[2]=orange

[root@oldboy ~]# array1[3]=peach

一次賦多個值,數組名=(多個變量值)

[root@oldboy ~]# array2=(tom jack alice)

[root@oldboy ~]# array3=(tom jack alice "bash shell")

[root@oldboy ~]# array4=(1 2 3 "linux shell" [20]=puppet)

將給文件中的每個行,做爲一個元數賦值給數組 array3

[root@oldboy ~]# array5=(`cat /etc/passwd`)

(2)查看數組賦值結果

#定義普通數組

[root@oldboy ~]# declare -a array

(3)訪問數組元數

統計數組元數的個數

[root@oldboy ~]# echo ${#array1[@]}

4

訪問數組中的第一個元數

[root@oldboy ~]# echo ${array1[0]}

pear

從數組索引1開始

[root@oldboy ~]# echo ${array1[@]:1}

apple orange peach

從數組索引1開始,訪問兩個元數

[root@oldboy ~]# echo ${array_fruit[@]:1:2}

apple orange

訪問數組中全部數據,至關於echo ${array1[*]}

[root@oldboy ~]# echo ${array_fruit[@]}

pear apple orange peach

(4)獲取數組索引

獲取數組元數的索引

[root@oldboy ~]# echo ${!array1[@]}

0 1 2 3

使用值來遍歷數組

#!/bin/bash

array_fruit=(

apple

orange

pear)

for i in ${array_fruit[*]}

do

   echo $i

done

使用索引來遍歷數組

#!/bin/bash

array_fruit=(apple orange prar)

for i in ${!array-fruit[*]}

do

   echo ${array_fruit[$i]}

done

實例1.利用bash for循環打印下面這句話中字母數不大於6的單詞

welcome to oldboyedu my name is oldboy

#!/bin/bash

declare -a array_word

array_word=(welcome to oldboyedu my name is oldboy)

for i in ${array-word[@]}

do

if [ ${#i} -le 6 ];then

  echo $i

fi

done

實例2.批量檢查多個網站地址是否正常

要求:

(1)    使用shell數組方法實現,檢測策略儘可能模擬用戶訪問

(2)    每10秒鐘作一次全部的檢查,沒法訪問的輸出報警

(3)    待檢測的地址以下.

http://blog.oldboyedu.com

http://blog.etiantian.org

http://oldboy.blog.51cto.com

http://10.0.0.7

分析:

1. 定義一個數組

2. 經過for打印數組列表

3. 經過wget/curl發給我url,經過訪問返回值判斷

4. 使用while true循環,sleep 10

#!/bin/bash

declare -a  array_url

array_url=(

http://blog.oldboyedu.com

http://blog.etiantian.org

http://oldboy.blog.51cto.com

http://10.0.0.7

)

while  true

do

   for n in ${array_url[*]}

   do

     wget -q -T 3 --tries=1  --spider $n

     if  [ $? -eq 0 ];then

       echo 「$n is ok」

     else

       echo 「$n is fail」

     fi

done

    sleep 2

done

3.關聯數組

(1)定義關聯數組,什麼是關聯數組

[root@oldboy ~]# declare -A tt_array_1

[root@oldboy ~]# declare -A tt_array_2

(2)給關聯數組進行賦值

數組名[索引號]=變量值

[root@oldboy ~]# tt_array1[index1]=pear

[root@oldboy ~]# tt_array1[index2]=apple

[root@oldboy ~]# tt_array1[index3]=orange

[root@oldboy ~]# tt_array1[index4]=peach

給關聯數組一次賦多個值

[root@oldboy ~]#tt_array2=([index1]=tom [index2]=jack [index3]=alice )

(3)查看關聯數組

[root@oldboy ~]#declare -A

(4)訪問數據元數

訪問數組中的第二個元數

[root@oldboy ~]# echo ${tt_array2[index2]}

jack

訪問數組中全部元數,等同於 echo${array1[*]}

[root@oldboy ~]# echo ${tt_array2[@]}

tom jack alice

訪問數組中全部元數索引

[root@oldboy ~]# echo ${!tt_array2[@]}

index1 index2 index3

4.遍歷數組

經過數字元數的索引進行遍歷(推薦)

注意:將統計的對象做爲數組的索引,僅針對關聯數組

實例1.統計/etc/passwd的shell數量

cat /etc/passwd | awk -F ‘.’ ‘{print $NF}’ |sort|uniq -c

[root@oldboy ~]# cat array_passwd_count.sh

#!/bin/bash

declare -A array_passwd

(1)對數組進行賦值

while read line

do

   type=$(echo $line |awk -F ‘.’  ‘{print $NF}’)

   let array_passwd[$type]++

done </etc/passwd

(2)對數組進行遍歷

for i in ${!array_passwd[@]}

do

echo 「shell:$i,eount: ${array_passwd[$i]}」

done

實例2.統計Nginx日誌IP訪問次數

cat /etc/httpd/logs/access_log | awk '{print $1}'| sort|uniq -c

[root@oldboy ~]# cat array_nginx_count.sh

#!/bin/bash

# nginx log top 10 IP conut

declare -A array_nginx

#1.給關聯數組的索引進行賦值

while read line

do

    type=$(echo $line|awk '{print $1}')

    let array_nginx[$type]++

done </var/log/nginx/access.log

 

for i in ${!array_nginx[@]}

do

    echo "IP是:$i 出現多少次${array_nginx[$i]}"

done

實例3.統計TCP的狀態信息

[root@oldboy ~]# cat array_tcp_state.sh

#!/bin/bash

declare -A array_tcp

type=$(ss -an |grep :80|awk '{print $1}')

#1.對數組進行的索引賦值

for i in $type

do

    let array_tcp[$i]++

done

#2.遍歷數組

for j in ${!array_tcp[@]}

do

    echo "當前的狀態是:$j,當前狀態出現了多少次:${array_tcp[$j]}"

done

 

 

當前的狀態是:ESTAB,當前狀態出現了多少次:325

當前的狀態是:CLOSE-WAIT,當前狀態出現了多少次:35

當前的狀態是:TIME-WAIT,當前狀態出現了多少次:14017

當前的狀態是:SYN-RECV,當前狀態出現了多少次:21

當前的狀態是:FIN-WAIT-1,當前狀態出現了多少次:37

當前的狀態是:LISTEN,當前狀態出現了多少次:1

shell編程第八天

一.shell正則應用

正則表達式介紹:

正則表達式`regular expression`, RE是一種字符模式,用於在查找過程當中匹配指定的字符。

在大多數程序裏,正則表達式都被置於兩個正斜槓之間;例如`/l[oO]ve/`就是由正斜槓界定的正則表達式,它將匹配被查找的行中任何位置出現的相同模式。在正則表達式中,元字符是最重要的概念。

正則表達式的做用

  1. 1.      linux正則表達式grep sed awk
  2. 2.      大量的字符串文件須要進行配置,並且是非交互的
  3. 3.      過濾相關的字符串,匹配字符串,打印字符串

正則表達式注意事項

  1. 1.      正則表達式應用很是普遍,存在於各類語言中,例如:php,Python,java等
  2. 2.      正則表達式和通配符是有本質區別的
  3. 3.      要想學好grep  sed  awk首先就要掌握正則表達式

二. 基礎正則表達式

元字符意義BRE,正則表達式時間就是一些特殊字符,賦予了它特定的含義

字符匹配:

. :匹配任單個字符;

[ ]:匹配指定範圍內的任意當個字符;

[^]:匹配指定範圍外的任意單個字符;

[a-z]:匹配全部小寫自字母

[A-Z]:匹配全部大寫字母

[0-9]:匹配全部數字

[a-z0-9]:匹配字母和數字

[abcd]:匹配括號裏有的字母

匹配次數:用子啊要指定其出現的次數的字符的後面,用於如今其前面字符出現的次數;

*:匹配其前面的字符任意次:0,1,屢次:

   例如:grep 「x*y」

        abxy,aby,xxxxy,yad

.*:匹配任意長度的任意字符;

\?:匹配其前面的字符0次或1次,也就是說其前面的字符是無關緊要的;

\+:匹配其前面的字符1次或屢次,也就是說其前面的字符至少出現1次;

\{m\}:匹配其前面的字符m次;

\{m,n\}:匹配其前面的字符至少m次,至多n次;

\{0,n\}:至多n次;

\{m,\}:至少m次;

位置錨定:

^:行首錨定;用於模式的最左側;

$:行尾錨定;用於模式的最右側;

^PATTERN$:用PATTERN來匹配整行;

       ^$:空白行;

       ^[[:space:]]*$:空行或包含空白字符的行;                                     

單詞:非特殊字符組成的連續字符串都稱爲單詞;

\<或\b:詞首錨定,用於單詞的左側;

\>或\b:詞尾錨定,用於單詞的右側;

\<PATHERN\>:匹配完整單詞;

三. 擴展正則表達式

擴展正則表達式:ERE,egrep,grep -E

擴展正則表達式的元字符:

字符匹配:

.:匹配任意單個字符;

[]:匹配指定範圍內的任意單個字符;

[^]:匹配指定範圍外的任意單個字符;

次數匹配:

  *:匹配其前面的字符任意次:0,1,屢次;

.*:匹配任意長度的任意字符;

  ?:匹配其前面的字符0次或1次,也就是說其前面的字符是無關緊要的;

  +:匹配其前面的字符1次或屢次,也就是說其前面的字符至少出現1次

  {m}:匹配其前面的字符m次;

{m,n}:匹配其前面的字符至少m次,至多n次;

       {0,n}:至多n次;

       {m,}:至少m次;      

位置錨定:

^:行首錨定;用於模式的最左側;

$:行尾錨定;用於模式的最右側;

^PATTERN$:用PATTERN來匹配整行;

       ^$:空白行;

       ^[[:space:]]*$:空行或包含空白字符的行;

\<PATTERN或\b:詞首錨定,用於單詞的左側;

PATTERN\>或\b:詞尾錨定,用於單詞的右側;

\<PATHERN\>:匹配完整單詞;

四. 正則表達式實戰

I am oldboy teacher!

I teach linux.

test

 

I like badminton ball ,billiard ball and chinese chess!

my blog is http://oldboy.blog.51cto.com

our site is http://www.oldboy.com

my qq num is 191868516.

not 191886888516.

//過濾以m開頭的行

[root@Shell ~]# grep "^m" test.txt

my blog is http://oldboy.blog.51cto.com

my qq num is 191868516.

[root@Shell ~]# grep "m$" test.txt

my blog is http://oldboy.blog.51cto.com

our site is http://www.oldboyedu.com

//排除空行, 並打印行號

[root@student ~]# grep -vn "^$" oldboy.txt

//匹配任意一個字符,不包括空行

[root@student ~]# grep "." oldboy.txt

//.匹配全部

[root@student ~]# grep ".*" oldboy.txt

//匹配單個任意字符

[root@node1 ~]# grep "oldboy.i" oldboy.txt

//以點結尾的

[root@student ~]# grep "\.$" oldboy.txt

//精確匹配到

[root@student ~]# grep -o "8*" oldboy.txt

//匹配有abc的行

[root@student ~]# grep "[abc]" oldboy.txt

//匹配數字所在的行"[^0-9]"

[root@student ~]# grep "[0-9]" oldboy.txt

//匹配全部小寫字母[^a-z]

[root@student ~]# grep "[a-z]" oldboy.txt

//重複0三次

[root@student ~]# grep "8\{3\}" oldboy.txt

//重複3個000不用轉義符

[root@student ~]# grep -E "8{3}" oldboy.txt

//重複數字8, 3-5次

[root@student ~]# grep -E "8{3,5}" test.txt

//至少1次或1次以上  

[root@student ~]# grep -E "8{1,}" oldboy.txt

五. sed文本處理

sed是一個流編輯器, 非交互式的編輯器,它一次處理一行內容.

處理時,把當前處理的行存儲在臨時緩衝區中,稱爲「模式空間」(pattern space)

接着用 sed 命令處理緩衝區中的內容,處理完成後, 把緩衝區的內容送往屏幕。

接着處理下一行,這樣不斷重複,直到文件末尾。

文件內容並無改變,除非你 使用重定向存儲輸出。

Sed 要用來自動編輯一個或多個文件;簡化對文件的反覆操做;編寫轉換程序等。

1.sed命令格式

sed [options] 'command' file(s)

sed正則使用

與 grep同樣,sed 在文件中查找模式時也可使用正則表達式(RE)和各類元字符。

正則表達式是括在斜槓間的模式,用於查找和替換,如下是sed支持的元字符。

使用基本元字符集 , $, ., *, [], < >, (), {}

使用擴展元字符集 ?, +, { }, |, ( )

使用擴展元字符的方式 + sed -r

2.sed命令示例

sed對指定行進行操做,包括打印、刪除、修改、追加等。

sed選項參數

-e 容許多項編輯

-n 取消默認的輸出

-i 直接修改對應文件

-r 支持擴展元字符

sed命令參數

a 在當前行後添加一行或多行

c 在當前行進行替換修改

d 在當前行進行刪除操做

i 在當前行以前插入文本

p 打印匹配的行或指定行

n 讀入下一輸入行,從下一條命令進行處理

! 對所選行之外的全部行應用命令

h 把模式空間裏的內容重定向到暫存緩衝區

H 把模式空間裏的內容追加到暫存緩衝區

g 取出暫存緩衝區的內容,將其複製到模式空間,覆蓋該處原有內容

G 取出暫存緩衝區的內容,將其複製到模式空間,追加在原有內容後面

多重編輯選項e

例:

//先刪除行,而後管道給後面的sed進行替換

[root@Shell ~]# sed '1,9d' passwd |sed 's#root#alex#g'

//使用-e進行屢次編輯修改操做

[root@Shell ~]# sed -e '1,9d' -e 's#root#alex#g' passwd

 

打印命令p

 

//打印匹配halt的行

[root@Shell ~]# sed -n  '/halt/p' passwd

halt:x:7:0:halt:/sbin:/sbin/halt

//打印第二行的內容

[root@Shell ~]# sed -n  '2p' passwd

bin:x:1:1:bin:/bin:/sbin/nologin

//打印最後一行

[root@Shell ~]# sed -n  '$p' passwd

 

追加命令a

//給30行添加配置 \t tab鍵(須要轉義) \n 換行符

[root@Shell ~]# sed -i  '30a listen 80;' passwd

修改命令c

//指定某行進行內容替換

[root@Shell ~]# sed  -i '7c SELINUX=Disabled' /etc/selinux/config

//正則匹配對應內容, 而後進行替換

sed -i '/^SELINUX=/cSELINUX=Disabled' /etc/selinux/config

//非交互式修改指定的配置文件

[root@Shell ~]# sed -ri '/UseDNS/cUseDNS no' /etc/ssh/sshd_config

[root@Shell ~]# sed -ri '/GSSAPIAuthentication/c#GSSAPIAuthentication no' /etc/ssh/sshd_config

[root@Shell ~]# sed -ri '/^SELINUX=/cSELINUX=disabled' /etc/selinux/config

刪除命令d

//指定刪除第三行, 但不會改變文件內容

[root@Shell ~]# sed '3d' passwd

[root@Shell ~]# sed '3{d}' passwd

//從第三行刪除到最後一行

[root@Shell ~]# sed '3,$d' passwd

//刪除最後一行

[root@Shell ~]# sed '$d' passwd

//刪除全部的行

[root@Shell ~]# sed '1,$d' passwd

//匹配正則進行該行刪除

[root@Shell ~]# sed '/mail/d' passwd

插入命令i

//在文件的某一行上面添加內容

[root@Shell ~]# sed -i  '30i listen 80;' passwd

 

寫文件命令w

//將匹配到的行寫入到新文件中

[root@Shell ~]# sed -n '/root/w newfile' passwd

 

//將passwd文件的第二行寫入到newfile中

[root@Shell ~]# sed -n '2w newfile' passwd

獲取下一行命令n

//匹配root的行, 刪除root行的下一列

[root@Shell ~]# sed '/root/{n;d}' passwd

 

//替換匹配root行的下一列

[root@Shell ~]# sed '/root/{n; s/bin/test/}' passwd

 

暫存和取用命令h H g G

 

//將第一行的寫入到暫存區, 替換最後一行的內容

[root@Shell ~]# sed  '1h;$g' /etc/hosts

//將第一行的寫入到暫存區, 替換最後一行的內容

[root@Shell ~]# sed  '1h;$g' /etc/hosts

 

//將第一行的寫入到暫存區, 在最後一行調用暫存區的內容

[root@Shell ~]# sed  '1h;$G' /etc/hosts

 

//將第一行的內容刪除但保留至暫存區, 在最後一行調用暫存區內容追加至於尾部

[root@Shell ~]# sed -r '1{h;d};$G' /etc/hosts

//將第一行的寫入到暫存區, 在最後一行調用暫存區的內容

[root@Shell ~]# sed  '1h;$G' /etc/hosts

 

//將第一行的內容刪除但保留至暫存區, 在最後一行調用暫存區內容追加至於尾部

[root@Shell ~]# sed -r '1{h;d};$G' /etc/hosts

 

//將第一行的內容寫入至暫存區, 從第二行開始進行重定向替換

[root@Shell ~]# sed -r '1h;2,$g' /etc/hosts

 

//將第一行重定向至暫存區, 2-3行追加至暫存區, 最後追加調用暫存區的內容

[root@Shell ~]# sed -r '1h; 2,3H; $G' /etc/hosts

 

反向選擇命令!

 

//除了第三行,其餘所有刪除

[root@Shell ~]# sed -r '3!d' /etc/hosts

六. sed匹配替換

s 替換命令標誌

g 行內全局替換

i 忽略替換大小寫

替換命令s

//替換每行出現的第一個root

[root@Shell ~]# sed 's/root/alice/' passwd

//替換以root開頭的行

[root@Shell ~]# sed 's/^root/alice/' passwd

//查找匹配到的行, 在匹配的行後面添加內容

[root@Shell ~]# sed -r 's/[0-9][0-9]$/& .5/' passwd

 

//匹配包含有root的行進行替換

[root@Shell ~]# sed -r 's/root/alice/g' passwd

//匹配包含有root的行進行替換,忽略大小寫

# sed -r 's/root/alice/gi' /etc/passwd

 

//後向引用

[root@Shell ~]# sed -r 's#(Roo)#\1-alice#g' /etc/passwd

[root@Shell ~]# ifconfig eth0|sed -n '2p'|sed -r 's#(^.*et) (.*) (net.*$)#\2#g'

 

//示例

[root@bgx ~]# vim a.txt

/etc/abc/456

etc

//刪除文本中的內容,需加轉義

[root@Shell ~]# sed -r '\/etc\/abc\/456/d' a.txt

//若是碰到/符號, 建議使用#符替換

[root@Shell ~]# sed -r 's#/etc/abc/456#/dev/null#g' a.txt

[root@Shell ~]# sed -r 's@/etc/abc/456@/dev/null@' a.txt

刪除文件

//刪除配置文件中#號開頭的註釋行, 若是碰到tab或空格是沒法刪除

[root@Shell ~]# sed '/^#/d' file

//刪除配置文件中含有tab鍵的註釋行

[root@Shell ~]# sed -r '/^[ \t]*#/d' file

//刪除無內容空行

[root@Shell ~]# sed -r '/^[ \t]*$/d' file

 

//刪除註釋行及空行

[root@Shell ~]# sed -r '/^[ \t]*#/d; /^[ \t]*$/d' /etc/vsftpd/vsftpd.conf

[root@Shell ~]# sed -r '/^[ \t]*#|^[ \t]*$/d' /etc/vsftpd/vsftpd.conf

[root@Shell ~]# sed -r '/^[ \t]*($|#)/d' /etc/vsftpd/vsftpd.conf

給文件行添加註釋

//將第二行到第六行加上註釋信息

[root@Shell ~]# sed '2,6s/^/#/' passwd

 

//將第二行到第六行最前面添加#註釋符

[root@Shell ~]# sed -r '2,6s/.*/#&/' passwd

 

//添加#註釋符

[root@Shell ~]# sed -r '3,$ s/^#*/#/' passwd

# sed -r '30,50s/^[ \t]*#*/#/' /etc/nginx.conf

# sed -r '2,8s/^[ \t#]*/#/' /etc/nginx.conf

七. awk文本處理

awk是一種編程語言,用於在`linux/unix`下對文本和數據進行處理。

awk數據能夠來自標準輸入、一個或多個文件,或其它命令的輸出。

awk一般是配合腳本進行使用, 是一個強大的文本處理工具。

 

awk 的處理文本和數據的方式以下:

 

1.進行逐行掃描文件, 從第一行到最後一行

2.尋找匹配的特定模式的行,在行上進行操做

3.若是沒有指定處理動做,則把匹配的行顯示到標準輸出

4.若是沒有指定模式,則全部被操做的行都被處理

awk 的兩種形式語法格式

 

awk [options] 'commands' filenames

awk [options] -f awk-script-file filenames

 

options

-F 定義輸入字段分隔符,默認的分隔符是空格或tab鍵

command

BEGIN{}        {}        END{}

行處理前       行處理    行處理後

[root@Shell ~]# awk 'BEGIN{print 1/2} {print "ok"} END {print "Game Over"}'  /etc/hosts

0.5

ok

ok

ok

Game Over

awk命令格式

//awk 'pattern' filename 匹配文件

[root@Shell ~]# awk '/root/' /etc/passwd

 

//awk '{action}' filename 對文件行進行動做處理

[root@Shell ~]# awk -F: '{print $1}' /etc/passwd

cut -d: -f1

 

//awk 'pattern {action}' filename 匹配+處理動做

[root@Shell ~]# awk -F ':' '/root/ {print $1,$3}' /etc/passwd

[root@Shell ~]# awk 'BEGIN{FS=":"} /root/{print $1,$3}' /etc/passwd

 

//command |awk 'pattern {action}' //判斷大於多少則輸出什麼內容

[root@Shell ~]# df |awk '/\/$/ {if ($3>50000) print $4}'

八. awk工做原理

# awk -F: '{print $1,$3}' /etc/passwd

1.awk使用一行做爲輸入,並將這一行賦給內部變量$0每一行也可稱爲一個記錄,以換行符結束

2.awk進行字段分解,每一個字段存儲在已編號的變量中,從$1開始

3.awk默認狀況下的分隔符是空格, 是由內部變量FS來肯定字段分隔符。初始FS爲空格

4.awk打印字段,將以設置的方法使用print函數打印

5.awk在打印的字段間加上空格,由於$1,$3 之間有一個逗號。逗號它映射爲另外一個內部變量,稱爲輸出字段分隔符OFS默認爲空格

6.awk輸出以後,將從文件中獲取另外一行,並將其存儲在$0中,覆蓋原來的內容,而後將新的字符串分隔成字段並進行處理。該過程將持續到全部行處理完畢

 

### 4.2Awk內部變量

`$0`保存當前記錄的內容

[root@Shell ~]# awk '{print $0}' /etc/passwd

 

`NR`控制輸入的總行數

//打印整個文本的行號

[root@Shell ~]# awk '{print NR,$0}' /etc/passwd

//打印文件的前三行

[root@Shell ~]# awk 'NR<=3' /etc/passwd

 

`FNR`記錄輸入文件的編號

[root@Shell ~]# awk '{print FNR,$0}' /etc/passwd /etc/hosts

NF保存行的最後一列內容

[root@Shell ~]# awk -F ":" '{print $1,$NF}' /etc/passwd

 

`FS`指定字段分割符,默認空格

//以冒號做爲字段分隔符

[root@Shell ~]# awk -F: '/root/{print $1, $3}' /etc/passwd

[root@Shell ~]# awk 'BEGIN{FS=":"} {print $1,$3}' /etc/passwd

//以空格冒號tab做爲字段分割

[root@Shell ~]# awk -F'[ :\t]' '{print $1,$2,$3}' /etc/passwd

 

`OFS`輸出字段分隔符

//,映射爲OFS,初始狀況下OFS變量是空格

[root@Shell ~]# awk -F: '/root/{print $1,$2,$3,$4}' /etc/passwd

[root@Shell ~]# awk 'BEGIN{FS=":"; OFS="+++"} /^root/{print $1,$2,$3}' /etc/passwd

 

`RS`輸入記錄分隔符,默認爲換行符

[root@Shell ~]# awk -F: 'BEGIN{RS=" "} {print $0}' /etc/hosts

 

`ORS`將文件每一行合併爲一行,以空格爲分割

[root@Shell ~]# awk -F: 'BEGIN{ORS=" "} {print $0}' /etc/hosts

 

//一般狀況下讓輸出分隔符爲換行符, 而後依次打印響應的字段

[root@Shell ~]# awk -F ":" 'BEGIN{OFS="\n"}{print $1,$2,$3,$4,$5,$6,$7}' passwd

//將RS記錄值標記爲冒號分割, 打印後至關於將每行的內容進行切割

[root@Shell ~]# awk 'BEGIN{RS=":"}{print $0}' passwd

 

`print`格式化輸出函數

[root@Shell ~]# date|awk '{print $2,"5月份""\n",$NF,"今年"}'

[root@Shell ~]# awk -F: '{print "用戶是:" $1 "\t 用戶uid:" $3  "\t 用戶gid:" $4}' /etc/passwd

 

printf 函數

[root@Shell ~]# awk -F: '{printf "%-15s %-10s %-15s\n", $1, $2, $3}' /etc/passwd

%s 字符類型

%d 數值類型

佔 15 字符

- 表示左對齊,默認是右對齊

printf 默認不會在行尾自動換行,加\n

九. awk模式動做

awk語句都由模式和動做組成。

模式部分決定動做語句什麼時候觸發及觸發事件。

若是省略模式部分,動做將時刻保持執行狀態。模式能夠是條件語句或複合語句或正則表達式。

1.awk正則表達式

//匹配記錄(整行)

[root@Shell ~]# awk '/^root/' /etc/passwd

[root@Shell ~]# awk '$0 ~ /^root/' /etc/passwd

 

//匹配字段:匹配操做符(~ !~)

[root@Shell ~]# awk '!/^root/' /etc/passwd

[root@Shell ~]# awk '$0 ~ !/^root/' /etc/passwd

2.比較表達式

比較表達式採用對文本進行比較,只有當條件爲真,才執行指定的動做。

比較表達式使用關係運算符,用於比較數字與字符串。

關係運算符

|運算符     |含義      |示例

|:---|:----|:----

|<       |小於         |x<y

|<=      | 小於或等於  | x<=y

|=       |等於         |x==y

|!=      |不等於       |x!=y

|>=      |大於等於     | x>=y

|>       | 大於        |x>y

//uid爲0的列出來

[root@Shell ~]# awk -F ":" '$3==0' /etc/passwd

//uid小於10的所有列出來

[root@Shell ~]# awk -F: '$3 < 10' /etc/passwd

//用戶登錄的shell等於/bin/bash

[root@Shell ~]# awk -F: '$7 == "/bin/bash" ' /etc/passwd

//第一列爲alice的列出來

[root@Shell ~]# awk -F: '$1 == "alice" ' /etc/passwd

//爲alice的用戶列出來

[root@Shell ~]# awk -F: '$1 ~ /alice/ ' /etc/passwd

[root@Shell ~]# awk -F: '$1 !~ /alice/ ' /etc/passwd

//磁盤使用率大於多少則,則打印可用的值

[root@Shell ~]# df |awk '/\/$/'|awk '$3>1000000 {print $4}'

 

十. awk條件表達式

[root@Shell ~]# awk -F: '$3>300 {print $0}' /etc/passwd

[root@Shell ~]# awk -F: '{if($3>300) print $0}' /etc/passwd

[root@Shell ~]# awk -F: '{if($3>5555){print $3} else {print $1}}' /etc/passwd

十一.   運算表達式

[root@Shell ~]# awk -F: '$3 * 10 > 500000' /etc/passwd

[root@Shell ~]# awk -F: 'BEGIN{OFS="--"} { if($3*10>50000) {print $1,$3} } END {print "打印ok"}' /etc/passwd

[root@Shell ~]# awk '/southem/{print $5 + 10}' datafile

[root@Shell ~]# awk '/southem/{print $5 + 10.56}' datafile

[root@Shell ~]# awk '/southem/{print $8 - 10}' datafile

[root@Shell ~]# awk '/southem/{print $8 / 2 }' datafile 

[root@Shell ~]# awk '/southem/{print $8 * 2 }' datafile

[root@Shell ~]# awk '/southem/{print $8 % 2 }' datafile

十二.   邏輯操做符和複合模式

&& 邏輯與

|| 邏輯或 

!  邏輯非

 

//匹配用戶名爲root而且打印uid小於15的行

[root@Shell ~]# awk -F: '$1~/root/ && $3<=15' /etc/passwd

//匹配用戶名爲root或uid大於5000

[root@Shell ~]# awk -F: '$1~/root/ || $3>=5000' /etc/passwd

awk示例1

# awk '/west/' datafile

# awk '/^north/' datafile

# awk '$3 ~ /^north/' datafile

# awk '/^(no|so)/' datafile

# awk '{print $3,$2}' datafile

# awk '{print $3 $2}' datafile

# awk '{print $0}' datafile

# awk '{print "Number of fields: "NF}' datafile

# awk '/northeast/{print $3,$2}' datafile

# awk '/^[ns]/{print $1}' datafile

# awk '$5 ~ /\. [7-9]+/' datafile

# awk '$2 !~ /E/{print $1,$2}' datafile

# awk '$3 ~ /^Joel/{print $3 "is a nice boy."}' datafile

# awk '$8 ~ /[0-9][0-9]$/{print $8}' datafile

# awk '$4 ~ /Chin$/{print "The price is $" $8 "."}' datafile

# awk '/Tj/{print $0}' datafile

# awk -F: '{print "Number of fields: "NF}' /etc/passwd

# awk -F"[ :]" '{print NF}' /etc/passwd

awk示例2

[root@Shell ~]# cat b.txt

bgx oldboy:is a:good boy!

 

[root@Shell ~]# awk '{print NF}' b.txt

4

[root@Shell ~]# awk -F ':' '{print NF}' b.txt

3

[root@Shell ~]# awk -F"[ :]" '{print NF}' b.txt

6

 

十三.   Awk條件判斷

`if`語句格式:

 

{ if(表達式){語句;語句;... }}

 

//打印當前管理員用戶名稱

[root@Shell ~]# awk -F: '{ if($3==0){print $1 "is adminisitrator"} }' /etc/passwd

//統計系統用戶數量

[root@Shell ~]# awk -F: '{ if($3>0 && $3<1000){i++}} END {print i}' /etc/passwd

//統計普通用戶數量

[root@Shell ~]# awk -F: '{ if($3>1000){i++}} END {print i}' /etc/passwd

 

`if...else` 語句格式:

{if(表達式){語句;語句;... }else{語句;語句;...}}

# awk -F: '{if($3==0){print $1} else {print $7}}' /etc/passwd

# awk -F: '{if($3==0) {count++} else{i++} }' /etc/passwd

# awk -F: '{if($3==0){count++} else{i++}} END{print " 管理員個數: "count ; print " 系統用戶數: "i}' /etc/passwd

 

`if...else if...else` 語句格式:

{if(表達式 1){語句;語句;... }else if(表達式 2){語句;語句;. .. }else{語句;語句;... }}

 

[root@Shell ~]# awk -F: '{ if($3==0){i++} else if($3>0 && $3<1000){j++} else if($3>1000) {k++}} END {print i;print j;print k}' /etc/passwd

[root@Shell ~]# awk -F: '{ if($3==0){i++} else if($3>0 && $3<1000){j++} else if($3>1000) {k++}} END {print "管理員個數"i; print "系統用戶個數" j; print "系統用戶個 數" }' /etc/passwd

管理員個數1

系統用戶個數29

系統用戶個數69

十四.   awk 循環語句

while循環

[root@Shell ~]# awk 'BEGIN{ i=1; while(i<=10){print i; i++} }'

[root@Shell ~]# awk -F: '{i=1; while(i<=NF){print $i; i++}}' /etc/passwd

[root@Shell ~]# awk -F: '{i=1; while(i<=10) {print $0; i++}}' /etc/passwd

[root@Shell ~]#cat b.txt

111 222

333 444 555

666 777 888 999

[root@Shell ~]# awk '{i=1; while(i<=NF){print $i; i++}}' b.txt

 

for循環

//C 風格 for

[root@Shell ~]# awk 'BEGIN{for(i=1;i<=5;i++){print i} }'

//將每行打印 10 次

[root@Shell ~]# awk -F: '{ for(i=1;i<=10;i++) {print $0} }' passwd

[root@Shell ~]# awk -F: '{ for(i=1;i<=10;i++) {print $0} }' passwd

[root@Shell ~]# awk -F: '{ for(i=1;i<=NF;i++) {print $i} }' passwd

十五.   awk數組實戰

[root@Shell ~]# awk -F: '{username[++i]=$1} END{print username[1]}' /etc/passwd

[root@Shell ~]# awk -F: '{username[i++]=$1} END{print username[1]}' /etc/passwd

[root@Shell ~]# awk -F: '{username[i++]=$1} END{print username[0]}' /etc/passwd

>注意:將須要統計的某個字段做爲數組的索引,最後對索引進行遍歷

1.按索引遍歷

[root@Shell ~]# awk -F: '{username[x++]=$1} END{for(i in username) {print i,username[i]} }' /etc/passwd

[root@Shell ~]# awk -F: '{username[++x]=$1} END{for(i in username) {print i,username[i]} }' /etc/passwd

2.統計`/etc/passwd` 中各類類型 shell 的數量

# awk -F: '{shells[$NF]++} END{ for(i in shells){print i,shells[i]} }' /etc/passwd

3.網站訪問狀態統計<當前時實狀態ss>

[root@Shell ~]# ss -an|awk '/:80/{tcp[$2]++} END {for(i in tcp){print i,tcp[i]}}'

4.統計當前訪問的每一個IP的數量<當前時實狀態 netstat,ss>

[root@Shell ~]# ss -an|awk -F ':' '/:80/{ips[$(NF-1)]++} END {for(i in ips){print i,ips[i]}}'

十六.   Awk數組案例

Nginx日誌分析,日誌格式以下:

log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '

                      '$status $body_bytes_sent "$http_referer" '

                      '"$http_user_agent" "$http_x_forwarded_for"';

 

52.55.21.59 - - [25/Jan/2018:14:55:36 +0800] "GET /feed/ HTTP/1.1" 404 162 "https://www.google.com/" "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; de) Presto/2.9.168 Version/11.52" "-"

 

1.統計2018年01月25日,當天的PV量

[root@Shell ~]# grep "25/Jan/2018" log.bjstack.log |wc -l

[root@Shell ~]# awk "/25\/Jan\/2018/" log.bjstack.log |wc -l

[root@Shell ~]# awk '/25\/Jan\/2018/ {ips[$1]++} END {for(i in ips) {sum+=ips[i]} {print sum}}' log.bjstack.log

//統計15-19點的pv量

[root@Shell ~]# awk '$4>="[25/Jan/2018:15:00:00" && $4<="[25/Jan/2018:19:00:00 {print $0}"' log.bjstack.log |wc -l

 

2.統計2018年01月25日,一天內訪問最多的10個IP

[root@Shell ~]# awk '/25\/Jan\/2018/ {ips[$1]++} END {for(i in ips){ print ips[i],i}}' log.bjstack.log |sort -rn|head

//統計15-19點訪問次數最多的10個IP

[root@Shell ~]# awk '$4>="[25/Jan/2018:15:00:00" && $4<="[25/Jan/2018:19:00:00"' log.bjstack.log |awk '{ips[$1]++} END {for(i in ips){print ips[i],i}}'|sort -rn|head

 

3.統計2018年01月25日,訪問大於100次的IP

[root@Shell ~]# awk '/25\/Jan\/2018/ {ips[$1]++} END {for(i in ips){if(ips[i]>10){print i,ips[i]}}}' log.bjstack.log

 

4.統計2018年01月25日,訪問最多的10個頁面($request top 10)

[root@Shell ~]# awk '/25\/Jan\/2018/ {request[$7]++} END {for(i in request){print request[i],i}}' log.bjstack.log |sort -rn|head

 

5.統計2018年01月25日,每一個URL訪問內容總大小($body_bytes_sent)

[root@Shell ~]# awk '/25\/Jan\/2018/ {request[$7]++;size[$7]+=$10} END {for(i in request){print request[i],i,size[i]}}' log.bjstack.log |sort -rn|head

 

6.統計2018年01月25日,每一個IP訪問狀態碼數量($status)

[root@Shell ~]# awk '{ip_code[$1 " " $9]++} END {for(i in ip_code){print ip_code[i],i}}' log.bjstack.log|sort -rn|head

 

7.統計2018年01月25日,訪問狀態碼爲404及出現的次數($status)

[root@Shell ~]# grep "404" log.bjstack.log |wc -l

[root@Shell ~]# awk '{if($9=="404") code[$9]++} END {for(i in code){print i,code[i]}}' log.bjstack.log

 

8.統計2018年01月25日,8:30-9:00訪問狀態碼是404

[root@Shell ~]# awk '$4>="[25/Jan/2018:15:00:00" && $4<="[25/Jan/2018:19:00:00" && $9=="404" {code[$9]++} END {for(i in code){print i,code[i]}}' log.bjstack.log

[root@Shell ~]# awk '$9=="404" {code[$9]++} END {for(i in code){print i,code[i]}}' log.bjstack.log

 

9.統計2018年01月25日,各類狀態碼數量

[root@Shell ~]# awk '{code[$9]++} END {for(i in code){print i,code[i]}}' log.bjstack.log

[root@Shell ~]# awk '{if($9>=100 && $9<200) {i++}

else if ($9>=200 && $9<300) {j++}

else if ($9>=300 && $9<400) {k++}

else if ($9>=400 && $9<500) {n++}

else if($9>=500) {p++}}

END{print i,j,k,n,p,i+j+k+n+p}' log.bjstack.log

 

[root@Shell ~]# awk '{if($9>=100 && $9<200) {i++}

else if ($9>=200 && $9<300) {j++}

else if ($9>=300 && $9<400) {k++}

else if ($9>=400 && $9<500) {n++}

else if($9>=500) {p++}}

END{print i?i:0,j?j:0,k?k:0,n?n:0,p?p:0,i+j+k+n+p}' log.bjstack.log

相關文章
相關標籤/搜索