shell腳本編程

一、編程基礎:

shell腳本是包含一些命令或聲明,并符合一定格式的文本文件

shell腳本的用途有:

  • 自動化常用命令

  • 執行系統管理和故障排除

  • 創建簡單的應用程序

  • 處理文本或文件

1)     第一步:使用文本編輯器來創建文本文件 script.sh 并編寫內容

格式要求:首行shebang    指明所要使用的shell類型

#!/bin/bash
#!/usr/bin/python
#!/usr/bin/perl

結合命令、變量、表達式、語句等編寫腳本內容

“#”號開頭的行為注釋行

#echo something
echo "test txte"

   

2)     第二步:運行腳本

給予執行權限,在命令行上指定腳本的絕對或相對路徑

]#chmod +x script.sh
]#./script.sh

直接運行解釋器,將腳本作為解釋器程序的參數運行

]#bash script.sh

    #bash:調試執行腳本

        -n    簡單檢查腳本語法錯誤

        -x    調試執行,顯示腳本運行過程

二、變量:

變量類型:

1)本地變量:作用域僅為當前shell進程

變量的定義:

    用戶定義的變量有字母數字及下劃線組成,

    變量名的第一個字符不能為數字.

    變量名是大小寫敏感的

變量的引用:

    ${name},$name

    " ": 雙引號 變量名會替換為其值
    ' ' :單引號 變量名不會替換

    查看變量:set
    撤銷變量:unset name

2)環境變量:作用域為當前變量及其子進程 對其他登錄用戶無效

變量賦值:
   export name=value
   declare -x name=value
  
bash內嵌了很多環境變量(一般為全大寫),用于定義bash工作環境

    PATH,HISTFILE,HISTSIZE,SHELL,HOME,UID,OLDPWD
    查看環境變量:export;declare -x;printenv;env
    撤銷環境變量:unset name

3)局部變量:作用域為某代碼片段 函數上下文

4)只讀變量(常量)
  declare -r name
  readonly name
   只讀變量無法重新設定,不支持撤銷,當前shell終止后撤銷

5)特殊變量

    $0 腳本文件路徑本身 basename
    $#:參數個數
    $*:所有參數  "chen he zhao"  所有參數合并為單個字符串
    $@:所有參數  "chen" "he" "zhao" 

    位置變量:

向腳本傳遞位置參數變量:
  scrip.sh argu1 argu2

對應
  $1,$2…${10},${11}…
  

輪替:
   shift#   去掉前#個參數   即${#+1}變成$1

數據類型:字符型,數值型

三、數值運算:

算術運算: + – * / % ^   *乘法有時需要轉義
  let var=expr
    $[expr]
    $((expr))
    $(expr argu1 argu2 argu3

 增強型賦值:
    let 
        i+=#    :i=$i+#
        i-=
        i*=
        i/=
        i%=
   自增/自減:
     let VAR=$($VAR+1)
     let VAR+=1
     let VAR++
      —

]#i=1
]#let i++
]#echo $i
]#2
]#let i+=2
]#echo $i
]#4
]#expr 3 + 4]#expr 3 \* 4]#echo 3*4|bc

四、邏輯運算:

    運算數:真(true,yes,on,1)

        假(false,no,off,0)

    1.與

        1 && 1 = 1

        1 && 0 = 0

        0 && 1 = 0

        0 && 0 = 0

    2.或

        1 || 1 = 1

        1 || 0 = 1

        0 || 1 = 1

        0 || 0 = 0

    3.非

        ! 1 = 0

        ! 0 = 1

    

    4.異或

        真真 假

        真假 真

    

    1)CMD1 && CMD2    如果真…就…

        CMD1為假 則CMD2不運行

        CMD1為真 則CMD2運行

    

    2)CMD1 || CMD2    如果假…就…

        CMD1為真 則CMD2不運行

        CMD1為假 則CMD2運行

    

五、bash測試類型:

測試表達式:

    test EXPRESSION

    [ EXPRESSION ]  表達式兩端須有空格

    [[ EXPRESSION ]]

1.數值測試:  [ $num1 -## $num2 ]   整數測試!

    -eq:等于

    -ne:不等于

    -gt:大于

    -ge:大于等于

    -lt:小于

    -le:小于等于

]#[ 5 -gt 4 ]&&echo 0
]#0

2.字符串測試: [[ "CHAR" # "CHAR" ]] ASCLL碼比較

    ==:是否等于

    >: 大于  ascll 編碼

    <: 小于

    !=:不等于

    =~:左側字符串 是否能夠被右側 模式匹配 

      *   -z "STRING":判斷變量是否為空;空位真,不空為假

    -n "STRING":判斷是否不空 空為假,不空為真

]#[[ root =~ r.*t ]]&&echo 0
]#0

3.文件測試:

 存在性測試:

    -a FILE

    -e FILE

        存在為真

 文件類型測試:[ -# /PATH/FILE ]

    -b 存在且為 塊設備

    -c 存在且為 字符設備文件

    -d 存在且為 目錄

    -f 存在且為 普通文件

    -p 存在且為 管道文件

    -S 存在且為 套接字文件

    -h|L  存在且為 符號鏈接文件

]#[ -d /etc ] && echo 0

]#0

4.文件權限測試:   以用戶 實際權限;   root用戶存在特權

      000  但對root可讀 可寫 不可執行

    -r 存在且 對當前用戶可讀

    -w 存在且 對當前用戶可寫

    -x 存在且 對對當前用戶可執行

 -特殊權限測試:

    -u 存在且有 suid

    -g 存在且有 sgid

    -k 存在且有 stick

 -文件是否非空:

   * -s 不空為真,空為假

 -時間戳:

    -N 文件自最近被讀后是否被修改過

 -從屬關系測試:

    -O 當前用戶是否 為文件屬主

    -G 當前用戶是否 屬于文件屬組

 -雙目測試:mtime 判斷修改時間

    FILE1 -ef FILE2 是否互為硬鏈接

   * FILE1 -nt FILE2 F1是否新于F2

    FILE1 -ot FILE2 F1是否舊于F2

-a = 且

-o = 或

]#a=6
]#[ $a -gt 0 -a $a -lt 9 ] && echo 0
]#0

六、腳本的狀態返回值:

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

自定義狀態退出狀態碼;

    exit [n]:     n 對應 $? 的值

     shell進程遇到exit 即結束  n=[0-255]

    利用命令狀態返回值判斷:

    0:成功

    1-255:失敗

#read [OPTION]   獲取用戶輸入信息,從而完成變量賦值

    -p ""設置提示信息

    -t # 設置超時時間

]#read -p "please enter a number:" num
]#please enter a number:5
]#echo $num
]#5

====作業

一、腳本

1、編寫腳本/root/bin/systeminfo.sh,顯示當前主機系統信息,包括主機名,IPv4地址,操作系統版本,內核版本,CPU型號,內存大小,硬盤大小。

#!/bin/bash
printf %-10s "hostname:"
echo "`hostname`"
printf %-10s "ip:"
echo  "`ifconfig|sed -nr 's/.*r:(.*) B.*/\1/p'`"
printf %-10s "kernel:"
echo  "`uname -r|tr ':' ':\t'`"
printf %-10s "OS:"
echo  "OS:\t\t`cat /etc/redhat-release`"
printf %-10s "CPU:"
echo  "`lscpu|grep "Model name"|tr -d " "|cut -d: -f2`"
printf %-10s "Mem:"
echo  "free|sed -n 2p|tr -s ' '|cut -d' ' -f2"
printf %-10s "DiskSize:"
echo  "`lsblk|sed -n 2p|tr -s " "|cut -d " " -f4`"

2、編寫腳本/root/bin/backup.sh,可實現每日將/etc/目錄備份到/root/etcYYYY-mm-dd中

#!/bin/bash
cp -a /etc /testdir/etc$(date +%F)&>/dev/null&&echo cp success||echo cp failuer

3、編寫腳本/root/bin/disk.sh,顯示當前硬盤分區中空間利用率最大的值

#!/bin/bash
echo "the max usage:`df|grep '/dev/sd.*'|tr -s ' '|cut -d' ' -f5|sort|tail -1`"

4、編寫腳本/root/bin/links.sh,顯示正連接本主機的每個遠程主機的IPv4地址和連接數,并按連接數從大到小排序

#!/bin/bash
netstat -t|tr -s ' ' ':'|cut -d: -f6|grep [0-9]|sort|uniq -c|sort -nr

5、寫一個腳本/root/bin/sumid.sh,計算/etc/passwd文件中的第10個用戶和第20用戶的ID之和

!/bin/bash
ID1=`sed -n ${1}p /etc/passwd|cut -d: -f3`
ID2=`sed -n ${2}p /etc/passwd|cut -d: -f3`
let sum=ID1+ID2
echo "sum:$sum"

6、寫一個腳本/root/bin/sumspace.sh,傳遞兩個文件路徑作為參數給腳本,計算這兩個文件中所有空白行之和

#!/bin/bash
blank1=`grep "^$" $1|wc -l`
blank2=`grep "^$" $2|wc -l`
let sum=blank1+blank2
echo "sum=$sum"

7、寫一個腳本/root/bin/sumfile.sh,統計/etc, /var, /usr目錄中共有多少個一級子目錄和文件

#!/bin/bash
s1=`ls /etc|wc -l`
s2=`ls /var|wc -l`
s3=`ls /usr|wc -l`
sum=$[s1+s2+s3]
echo "sum=$sum"

8、寫一個腳本/root/bin/argsnum.sh,接受一個文件路徑作為參數;如果參數個數小于1,則提示用戶“至少應該給一個參數”,并立即退出;如果參數個數不小于1,則顯示第一個參數所指向的文件中的空白行數

#!/bin/bash
echo -n "please enter a path:"
read path
[ ! -e $path ] &&  echo "file does not exist" && exit 5 || grep -c "^[[:space:]]*$" $path
#[[ $# -lt 1 ]] && echo "at least one arg" && exit 5 || grep -c "^[[:space:]]*$" $1

9、寫一個腳本/root/bin/hostping.sh,接受一個主機的IPv4地址做為參數,測試是否可連通。如果能ping通,則提示用戶“該IP地址可訪問”;如果不可ping通,則提示用戶“該IP地址不可訪問”

#!/bin/bash
read -p "please ernter a ip adddress:" addr
ping $addr -W1 -c1&>/dev/null && echo "IP address rechable!" || echo "IPaddress unrechable!"

10、判斷硬盤的每個分區空間和inode的利用率是否大于80,如果是,發郵件通知root磁盤滿

#!/bin/bash
disk=`df |grep "/dev/sd.*"|cut -c 44-46|sort -nr|head -1`
inode=`df -i|grep "/dev/sd.*"|cut -c 40-42|sort -nr|head -1`
[ $disk -gt 80 -o $inode -gt 80 ]&&echo 'disk fulling'|mail root||echo dont worry

11、指定文件做為參數,判斷文件是否為.sh后綴,如果是,添加x權限

#!/bin/bash
[ ! -e $1 ]&&echo "file dose not exist!"&&exit 23
[[ $1 =~ .*\.sh$ ]]&&chmod +x $1&&echo '+x done'||echo not sh

12、判斷輸入的IP是否為合法IP

#!/bin/bash
echo -n "please enter a ip:"
read ip
echo  $ip|egrep -q "^(\<([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 legal ip || echo illegal ip

13、計算1+2+3+…+100

#!/bin/bash
seq -s '+' 1 100|bc

14、輸入起始值A和最后值B,計算從A+(A+1)…+(B-1)+B的總和

#!/bin/bash
seq -s '+' $1 $2|bc

原創文章,作者:Jasper,如若轉載,請注明出處:http://www.www58058.com/34844

(0)
JasperJasper
上一篇 2016-08-15
下一篇 2016-08-15

相關推薦

  • 運維工程師技能需求排行

    這是我今天在拉勾網搜索運維,翻完了4四頁也招聘信息之后得到的,我的目的是想要看看之后的學習,哪個更應該成為重點,有些在我意料之中,有些還真的沒想到,算是努力了一個小時的收獲吧,分享給大家。
    注意:其中的看法僅代表個人觀點,很多都是依靠我自己的學習經驗和工作經驗累積的

    Linux干貨 2017-12-12
  • linux中進程及內存管理工具

    pstree 顯示進程樹 ({}是線程) 選項-p #顯示進程編號 pstree username #查看指定用戶的進程 centos7中可以使用選項-s來查看指定進程的父子進程   ps (默認顯示當前終端運行的進程) 支持三種選項: 1、UNIX選項 -C cmdlist 指定命令(允許同時指定多個命令) -L 顯示線程 -e: 顯示所有進程,…

    Linux干貨 2017-12-17
  • linux查找命令locate、find

    本次博主來介紹下超實用的查找命令,沒有查不到,只有做不到。 直接上干貨:查找命令:locate和find,常用find,我們重點介紹find locate 通過查詢系統上預建的文件索引數據庫全盤查找所需文件,locate是透過update程序將硬盤中的所有檔案和目錄資料先建立一個索引數據庫,在執行loacte時直接找該索引,查詢速度會較快,索引的構建是在系統…

    2017-08-12
  • 簡單的啟動排錯

    一、出現 grub> 字樣,等待交互式輸入指令,說明MBR中Bootloader的stage1、stage1_5、stage2都正常,但丟失了/boot/grub.conf 文件,所以無法加載啟動項菜單,就無法讀取默認啟動的kernel、initrd等文件路徑。 解決辦法:無需救援模式,直接在此交互式界面指定相關文件的加載路徑。 (1) grub&gt…

    Linux干貨 2016-11-26
  • 由Linux中一個小問題引發的思考

    一、一個小問題 1、在學習Linux中我們經常會遇到很多有趣的小問題,今天筆者就遇到了一個很有意思的小問題,現在分享給大家:      “如何在本機字符終端登陸時,除顯示原有信息外,再顯示當前終端號,時間和主機名?” 2、實現方法如下:      輸入vim /etc/…

    2017-07-16
  • 私有IP網子網掩碼劃分原則及計算方法

    私有IP網子網掩碼劃分原則及計算方法 最好記下的二進制轉換十進制 00000000 0 00000001 1 00000010 2 00000100 4 00001000 8 00010000 16 00100000 32 01000000 64 10000000 128 11000000 192 11100000 224 11110000 240 1111…

    Linux干貨 2017-05-02
欧美性久久久久