shell腳本編程

shell俗稱殼(用來區別于核),提供使用者使用界面(命令解析器),它接受用戶命令,然后調用相應的應用程序。

同時它還是一種程序設計語言,作為命令語言,它交互式解釋和執行用戶輸入的命令或者自動地解釋和執行預先設計好的一連串的命令。作為程序涉及語言,它定義了各種變量和參數,并提供了許多在高級語言中才具有的控制結構,包括循環和分支。

一、shell腳本基礎概念

    shell的編程風格是過程式,即以指令為中心,數據服務指令。

    shell程序提供了編程能力,解釋執行。

    shell編程語言的基本結構

        數據存儲:變量、數組

        表達式:a+b

        語句:if

    shell編程邏輯處理方式

        順序執行

        循環執行

        選擇執行

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

        格式要求:首行shebang機制

        #!/bin/bash

        #!/usr/bin/python

        #!/usr/bin/perl

    shell腳本的用途

        自動化常用命令

        執行系統管理和故障排除

        創建簡單的應用程序

        處理文本或文件

    創建shell腳本

        第一步:使用文本編輯器來創建文本文件

            第一行必須包括shell聲明序列:#!

                #!/bin/bash

            添加注釋

                注釋以#開頭

        第二步:運行腳本

            給予執行權限,chmod +x file.sh 在命令行上指定腳本的絕對或相對路徑

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

    腳本調試

        bash -n /wang/jiaoben.sh

        檢查腳本中的語法錯誤

        bash -x /wang/jiaoben.sh

        調試執行

[root@localhost wang]# bash -x jiaoben1.sh 
+ wang=100
+ echo 100
100
++ 200
jiaoben1.sh: line 5: 200: command not found
+ laowang=
+ echo ''
注:一邊執行,一邊檢查語法:jiaoben1.sh第五行 200這個命令找不到

二、變量

    命名的內存空間

        數據存儲方式

            字符:

            數值:整型,浮點型

    變量類型

        作用

            數據存儲格式

            參與的運算

            表示的數據范圍

        類型

            字符

            數值:整型,浮點型

    強類型:定義變量時必須指定類型,參與運算必須符合類型要求,調用未聲明變量會產生錯誤

        例:java,python

    弱類型:無須指定類型,默認均為字符型,參與運算會自動進行隱式類型轉換,變量無須事先定義可直接調用

        例:bash 不支持浮點數

    變量命名法則:

        不能使用程序中的保留字,例:if,for

        只能使用數字、字母及下劃線,且不能以數字開頭

        見明知億

        統一命名規則:駝峰命名發,例:大駝峰SumFile,小駝峰sumFile

    bash中變量的種類

        根據變量的生效范圍等標準

        本地變量:生效范圍為當前shell進程,對當前shell之外的其它shell進程,包括當前shell的子shell進程均無效。

        環境變量:生效范圍為當前shell進程及其子進程

        局部變量:生效范圍為當前shell進程中某代碼片段(通常指函數)

        位置變量:$1,$2…來表示,用于讓腳本在腳本代碼中調用通過命令行傳遞給它的參數

        特殊變量:$?,$0,$*,$@,$#

            

    本地變量

         變量賦值:name=‘函數(value)’

        可以使用引用value:

            可以是直接字符串:name=“root”

            變量引用:name=“$USER”

            命令引用:name=`command`或name=$(command)

        變量引用:${name},$name

            "":弱引用,其中的變量引用會被替換為變量值

            '':強引用,其中的變量引用不會被替換為變量值,而保持原字符串

        顯示已定義的所有變量:set

        刪除變量:unset name

        本地變量不可給子shell進程使用。

[root@localhost wang]# cat jiaoben1.sh 
#!/bin/bash
wang=100
echo $wang
[root@localhost wang]# bash jiaoben1.sh 
100
[root@localhost wang]# echo $wang

[root@localhost wang]#

    環境變量

        變量聲明、賦值

            export name=value

            declare -x name=value

        變量引用:${name},$name

        顯示所有環境變量

            export

            env

            printenv

        刪除環境變量

            unset name

        環境變量可以在當前shell生效,exit退出就不會生效,可以給子進程使用

        bash有許多內建的環境變量:PATH,SHELL,USER,UID,HISTSIZE,HOME,PWD,OLDPWD,HOSTFILE,PS1

[root@localhost wang]# export wang=100
[root@localhost wang]# cat jiaoben1.sh 
#!/bin/bash

echo $wang
[root@localhost wang]# bash jiaoben1.sh 
100

    只讀變量

        只能聲時,但不能修改和刪除

        readonly name

        declare -r name

        定義之后永久保存在緩存中,exit退出即可取消定義

[root@localhost wang]# readonly wang=1
[root@localhost wang]# echo $wang
1
[root@localhost wang]# wang=2
-bash: wang: readonly variable
[root@localhost wang]# wang=1
-bash: wang: readonly variable

    位置變量

        在腳本代碼中調用通過命令行傳遞給腳本的參數

        $1,$2…:對應第1,第2等參數,shift[n]換位置

        $0:命令本身

        $*:傳遞給腳本的所有參數,全部參數合為一個字符串

        $@:傳遞給腳本的所有參數,每個參數為獨立字符串

        $#:傳遞給腳本的參數的個數

            $@,$*只在被雙引號包起來的時候才會有差異

[root@localhost wang]# cat jiaoben1.sh 
#!/bin/bash
echo "第一個參數是$1"
echo "第二個參數是$2"
echo "第三個參數是$3"
echo "所有參數是$*"
echo "所有參數是$@"
echo "參數的個數是$#"
[root@localhost wang]# bash jiaoben1.sh aaa bbb ccc
第一個參數是aaa
第二個參數是bbb
第三個參數是ccc
所有參數是aaa bbb ccc
所有參數是aaa bbb ccc
參數的個數是3
[root@localhost wang]# cat jiaoben1.sh 
#!/bin/bash
maxuid=`cat $1 | cut -d: -f3 |sort -nr | head -n1`
echo "$maxuid" 
[root@localhost wang]# bash jiaoben1.sh /etc/passwd
1000

三、算術運算

    bash中的算術運算:help let

        +,-,*,/,%(取余),**(乘方)

    實現算術運算

        let var=算術表達式

        var=$[算術表達式]

        var=$((算術表達式))

        var=$(expr arg1 arg2 arg3…)

        echo '算術表達式' |bc

        declare -i var=數值

    乘法符號有些場景中需要轉義。例:*

    bash有內建的隨機數生成器:$RANDOM(0-32767)

[root@localhost ~]# let wang=2*3
[root@localhost ~]# echo $wang
6
[root@localhost ~]# wang=$[3*4]
[root@localhost ~]# echo $wang
12
[root@localhost ~]# wang=$((1+3+4))
[root@localhost ~]# echo $wang
8
[root@localhost ~]# echo "3*(5+6)"|bc
33
[root@localhost ~]# echo $[RANDOM%10]
1
[root@localhost ~]# echo $[RANDOM%10]
6
[root@localhost ~]# echo $[RANDOM%10]
5

四、邏輯運算

    

    true:1    false: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,第二個必須要參與運算

            command1 command2

            command1成功,執行command2

            command1失敗,不執行command2

        短路或||

            第一個為1,結果必定為1

            第二個為0,第二個必須要參加運算

                command1 command2

            command1成功,不執行command2

            command1失敗,執行command2

        異或:^

            異或的兩個值,相同為假,不同為真

五、聚集命令

    有兩種聚集命令的方法

        復合式:date; who|wc -l

            命令會一個接一個的運行

        子shell:(date; who|ec -l)>>/tmp/trace

            所有的輸出都被發送給單個輸出和輸入


[root@localhost sh.log]# date;hostname;who
Thu Aug 11 19:49:53 CST 2016
localhost.localdomain
root     tty1         2016-08-09 17:41
root     pts/0        2016-08-11 18:53 (192.168.1.106)
root     pts/3        2016-08-11 14:06 (192.168.1.106)
[root@localhost sh.log]# date;hostname;who|wc -l
Thu Aug 11 19:50:08 CST 2016
localhost.localdomain
3
[root@localhost sh.log]# (date;hostname;who)|wc -l
5
[root@localhost sh.log]# (date;hostname;who)|wc -l

六、退出狀態

    進程使用退出狀態來報告成功或失敗

        0 代表成功,1-255代表失敗

        $?變量保存最近的命令退出狀態

[root@localhost sh.log]# ping -c1 -W1 192.168.1.1 &> /dev/null
[root@localhost sh.log]# echo $?
0
[root@localhost sh.log]# ping -c1 -W1 192.168.1.256 &> /dev/null
[root@localhost sh.log]# echo $?
2
[root@localhost sh.log]# useradd wang
[root@localhost sh.log]# grep -q "laowang" /etc/passwd
[root@localhost sh.log]# echo $?
1
[root@localhost sh.log]# grep -q "wang" /etc/passwd
[root@localhost sh.log]# echo $?
0

    退出狀態碼

        bash自定義退出狀態碼

        exit[n]:自定義退出狀態碼

        注:腳本中一旦遇到exit命令,腳本會立即終止,終止退出狀態取決與exit命令后面的數字

        注:如果未給腳本制定退出狀態碼,整個腳本的退出狀態碼取決于腳本中執行的最后一條命令的狀態碼

七、條件測試

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

    專用的測試表達式需要由測試命令輔助完成測試過程

    評估布爾聲明,以便用在條件性執行中

        若真,則返回0

        若假,則返回1

    測試命令

        test expression

        [ expression ]

        [[ expression ]]

        注:expression前后必須有空白字符

    條件性的執行操作符

        根據退出狀態而定,命令可以有條件地運行

            &&代表條件性的and then

            ||代表條件性的or else

[root@localhost sh.log]# ping -c1 -W1 192.168.1.1 &> /dev/null && echo "能ping通" || echo “不能ping通”
能ping通
[root@localhost sh.log]# ping -c1 -W1 192.168.1.256 &> /dev/null && echo "能ping通" || echo "不能ping通"
不能ping通

    bash測試類型

        數值測試

        -gt:是否大于

        -ge:是否大于等于

        -eq:是否不等于

        -ne:是否小于

        -le:是否小于等于

    字符串測試

        ==:是否等于

        >:ascii碼是否大于ascii碼

        <:是否小于

        !=:是否不等于

        =~:左側字符串是否能夠被右側的pattern所匹配

            注:此表達式一半用于[[]]中

        -z‘string’:字符串是否為空,空為真,不空為假

        -n‘string’:字符串是否不空,不空為真,空為假

            注:用于字符比較時的用到的操作數都應該使用引號

[root@localhost wang]# cat jiaoben1.sh 
#!/bin/bash

maxdisk=`df|grep "^tmpfs"|tr -s " " "%" |cut -d% -f5|sort -nr|head -n1`
maxshiyonglv=80
[ $maxdisk == $maxshiyonglv ] && echo "磁盤空間要爆滿" || echo "磁盤空間沒爆滿"

[root@localhost wang]# bash jiaoben1.sh 
磁盤空間沒爆滿
[root@localhost wang]# cat jiaoben2.sh 
#!/bin/bash
maxdisk=`df|grep "^tmpfs"|tr -s " " "%" |cut -d% -f5|sort -nr|head -n1`
maxshiyonglv=80
[ $maxdisk -gt $maxshiyonglv ] && echo "磁盤空間要爆滿" || echo "磁盤空間沒爆滿"
[root@localhost wang]# bash jiaoben2.sh 
磁盤空間沒爆滿

    文件測試

        存在性測試

            -a file:同-e

            -e file:文件存在性測試,存在為真,否則為假

        存在性及類別測試

            -b file:是否存在且為塊設備文件

            -c file:是否存在且為字符設備文件

            -d file:是否存在且為目錄文件

            -f file:是否存在且為普通文件

            -z file:文件是否存在

            -h file 或-L file :存在且為符號鏈接文件

            -p file:是否存在且為命名管道文件

            -S file:是否存在且為套接字文件

        文件權限測試

            -r file:是否存在且可讀

            -w file:是否存在且可寫

            -x file:是否存在且可執行

        文件特殊權限測試

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

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

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

        文件大小測試

            -s file:是否存在且非空

        文件是否打開

            -t fd:fd表示文件描述符是否已經打開且與某終端相關

            -N file:文件自動上一次被讀取之后是否被修改過

            -O file:當前有效用戶是否為文件屬主

            -G file:當前有效用戶是否為文件屬組

        雙目測試

            file1 -ef file2:file1與file2是否指向同一個設備上的相同inode

            file1 -nt file2:file1是否新于file2

            file1 -ot file2:file1是否舊于file2

        組合測試條件

            第一種方式

                command1 && aommand2 并且

                command1 || aommand2 或者

                !command 非

                如:[ -e file ] && [ -r file ]

            第二種方式

                expression1 -a expression2 并且

                expression1 -o rxpression2 或者

                !expression

                必須使用測試命令進行

[wang@www wang]$ ll
total 16
----------. 1 root root    0 Aug 11 23:36 file1
-rwxrwxrwx. 1 root root   16 Aug 11 11:21 file2
drwxr-xr-x. 2 root root 4096 Aug 11 10:11 jiaoben
-rwxr-xr-x. 1 root root  111 Aug 12 00:30 jiaoben1.sh
-rw-r--r--. 1 root root  110 Aug 11 23:28 jiaoben2.sh
[wang@www wang]$ cat jiaoben1.sh 
#!/bin/bash

[ -r $1 -o -x $1 ] && echo "該文件有讀或寫權限" || echo "該文件沒有讀或寫權限"
[wang@www wang]$ bash jiaoben1.sh file1
該文件沒有讀或寫權限
[wang@www wang]$ bash jiaoben1.sh file2
該文件有讀或寫權限
[wang@www wang]$ cat jiaoben2.sh 
#!/bin/bash

[ -r $1 -a -x $1 ] && echo "這個文件有讀寫權限" ||echo "這個文件沒有讀寫權限"
[wang@www wang]$ bash jiaoben2.sh file1
這個文件沒有讀寫權限
[wang@www wang]$ bash jiaoben2.sh file2
這個文件有讀寫權限

    使用read來輸入值分配給一個或多個shell變量

        -p 指定要顯示的提示

        -t timeout

    read 從標準輸入中讀取值,給每個單詞分配一個變量

    所有剩余單詞都被分配給最后一個變量

        read -p “Enter a filename:” FILE

[root@www wang]# cat jiaoben1.sh 
#!/bin/bash
read -p "input a number:"
[root@www wang]# bash jiaoben1.sh 
input a number:laowang

    流程控制

        過程是編程語言

        順序執行

        選擇執行

        循環執行

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

(0)
DYWDYW
上一篇 2016-08-15
下一篇 2016-08-16

相關推薦

  • linux用戶管理(一)

    作為一個專業的服務器發行版,CentOS上存在著n多個用戶,作為一個專業的運維工程師,linux的用戶管理和用戶組的管理是做為一個SA必不可少的工作. 下面我們就先來談談linux中的用戶管理: useradd可以在系統中新建一個用戶 用法如下: useradd [選項] 用戶名 常用選項: -u 指定用戶的UID -g 指定用戶的初始組ID -G…

    Linux干貨 2017-04-03
  • Puppet基于Master/Agent模式實現LNMP平臺部署

    前言 隨著IT行業的迅猛發展,傳統的運維方式靠大量人力比較吃力,運維人員面對日益增長的服務器和運維工作,不得不把很多重復的、繁瑣的工作利用自動化處理。前期我們介紹了運維自動化工具ansible的簡單應用,本期帶來的是運維自動化神器puppet基于Master/Agent模式實現LNMP平臺部署。 Puppet 簡介 Puppet是基于ruby語言開發的一種L…

    Linux干貨 2015-07-13
  • linux文件管理類命令學習總結練習

    1、常用文件管理類命令:cp, mv, rm   cp: copy命令       單元復制 cp [OPTION]… [-T] SOURCE DEST                     DEST不存在…

    Linux干貨 2016-11-06
  • 用戶、組的創建和管理

    用戶的創建 useradd usermod userdel useradd:創建用戶 create a new user or update default new user information     useradd [options]… LOGIN     &…

    Linux干貨 2016-08-03
  • 實驗驗證Linux系統環境下路由的最長掩碼匹配原則

    實驗驗證Linux系統環境下路由的最長掩碼匹配原則 實驗環境拓撲如下 環境配置 HostA網卡配置 DEVICE=eth1 IPADDR=172.16.0.100 PREFIX=16 R1網卡配置 DEVICE=eth1 IPADDR=172.16.0.1 PREFIX=16 DEVICE=eth2 IPADDR=192.168.2.1 PREFIX=24 …

    2017-05-02
  • 最簡單也最難:運維監控的最后1公里

    談運維我們不得不提監控,監控是運維的起點,也是難點。隨著IT架構逐漸復雜化,從前端到IT底層,中間涉及瀏覽器、網絡、服務器、操作系統、中間件、應用、數據庫等,每個環節廠商不盡相同。當出現異常需要定位哪個環節出了問題的時候,排查就耗時耗力,若使用優云監控產品,以上難題不再是問題。優云全棧運維監控覆蓋了所有環節的監控,真正做到監控無盲區,運維無隱患。 運維最后一…

    系統運維 2017-01-09
欧美性久久久久