shell編程

   編程基礎

  編程基礎

      編程:也就是程序+數據

          程序編程風格:

                 過程式:以指令為中心,數據服務于指令

                 對象式:以數據為中心,指令服務于數據

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

程序的執行式:

       計算機只能運行二進制指令

            編程語言:

                 低級:匯編

                 高級:

                 編譯:高級語言–> 編譯器–> 目標代碼

                          java,C#

                 解釋:高級語言–> 解釋器–> 機器代碼

                          shell, perl, python

   編程的基本概念

          編程邏輯處理方式:

                                順序執行、循環執行、選擇執行

          shell 編程:過程式、解釋執行

          編程語言的基本結構:

                      數據存儲:變量、數組

                      表達式: a + b

                      語句:if

       shell腳本基礎

 shell腳本基礎:

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

         格式要求:首行shebang 機制

                      #!/bin/bash

                      #!/usr/bin/python

                      #!/usr/bin/perl

         shell 腳本的用途有:

                  *自動化常用命令

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

                  *創建簡單的應用程序

                  *處理文本或文件

  創建shell腳本

           第一步:使用文本編輯器來創建文本文件,以.sh結尾的文件

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

                                           #!/bin/bash

             添加注釋:注釋以#開頭

           第二步:運行腳本

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

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

  shell腳本示例

#!/bin/bash
#author:quan
#Version: 1.0
#Description:This script displays some information about your# environment
echo "Greetings. The date and time are $(date)"
echo "Your working directory is: $(pwd)"

     執行一下,看看結果:

blob.png

  腳本調試

      bash -n /path/to/some_script   檢測腳本中的語法錯誤

      bash -x /path/to/some_script   調試執行

  變量

變量:命名的內存空間

        數據存儲方式:

                        字符

        數值:整型,浮點型

       變量:變量類型

        作用:

               1 、數據存儲格式

               2 、參與的運算

               3 、表示的數據范圍

         類型:

               字符

               數值:整型、浮點型

               強類型:定義變量時必須指定類型、參與運算必須符合類型

          要求;調用未聲明變量會產生錯誤

                  如 java,python

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

           如:bash 不支持浮點數

         變量命名法則:

              1、不能使程序中的保留字:例如if, for;

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

              3、見名知 義

              4、統一命名

   bash中變量的種類

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

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

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

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

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

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

    本地變量

         變量賦值:name=‘value’, ,

         可以使用引用value:

            (1)可以是直接字串; name=“root"

            (2) 變量引用:name="$USER"

            (3) 命令引用:name=` COMMAND `, name =$(COMMAND)

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

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

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

         持原字符串

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

            刪除變量:unset name



   課堂小練

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

首先:vi /root/bin/systeminfo.sh 編輯腳本

#!/bin/bash
echo Hostname: `hostname`;
echo IP address: `ifconfig|egrep -o "[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}"|head -n1`; 
echo System version: `cat /etc/system-release`;
echo kernel version: `uname -r`;
echo CPU type : `lscpu |grep 'Model name'|sed 's/.*://'|sed 's/^[[:space:]]\+//'`;
echo Disk size :`fdisk -l|grep "sda:"|sed 's/.*:'//|sed 's/,.*'//|sed 's/^[[:space:]]\+'//`
echo Memory size : `free -m|grep "Mem"|tr -s [[:space:]]|cut -d" " -f 2` MB

編寫完畢,:wq存盤退出

執行一下程序:

blob.png

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

首先:vi /root/bin/backup.sh

#!/bin/bash
#
cp -a /etc /root/etc`date +%F`

然后,:wq存盤退出,然后執行下程序,查看/root下文件

blob.png

已經生成了今天的etc文件

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

首先:vi /root/bin/disk.sh

#!/bin/bash
echo "The max using rate is:`df |grep "/dev/sd"| cut -c 44-46 | sort -nr | head -1`%"

然后:wq存盤退出,執行程序:

blob.png

 4 、編寫腳本/root/bin/links.sh, 顯示正連接本主機的每個遠程主機的IPv4

首先,vi /root/bin/links.sh

#!/bin/bash
echo "the links number is:"
netstat -nt |tr -s ' ' |cut -d ' ' -f5 |cut -d: -f1 |grep [0-9]|sort |uniq -c|sort -nr

:wq存盤退出,執行程序

blob.png

  環境變量

          變量聲明、賦值:

                             export name=VALUE

                            declare -x name=VALUE

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

          顯示所有環境變量:

                                export

                                env

                                printenv

          刪除:unset name

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

  只讀、位置變量

          只讀變量:只能聲時,但不能修改和刪除

                       readonly name

                       declare -r name

位置變量:在腳本代碼中調用通過命令行傳遞給腳本的參數

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

                $0: 命令本身

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

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

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

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

          示例:判斷給出的文件的行數

                  linecount="$(wc -l $1| cut -d' ' -f1)"

                  echo "$1 has $linecount lines."

首先,創建腳本vi 2.sh

#!/bin/bash
linecount="$(wc -l $1| cut -d' ' -f1)"
echo "$1 has $linecount line

然后執行文件,比如查看/etc/issue行數:  

blob.png

算術運算

        bash 中的算術運算:help let

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

 實現算術運算

               (1) let var= 算術表達式

               (2) var=$[ 算術表達式]

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

               (4) var=$(expr arg1 arg2 arg3 …)

               (5) declare –i var = 數值

               (6) echo ‘ 算術表達式’ | bc

          乘法符號有些場景中需要轉義 ,如 如*

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

echo $[$RANDOM%50] :0-49,%表示取模

blob.png

   賦值

           增強型賦值:

                  +=, -=, *=, /=, %=

                  let varOPERvalue

                  例如:let count+=3  自加3后自賦值

                  自增,自減:

                            let var+=1

                            let var++

                            let var-=1

                            let var–



練習

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

vi /root/bin/sumid.sh

#!/bin/bash
#
#Shows the sum of the two users
sum="`cat /etc/passwd | sed -n -e '10p' -e '20p' | cut -d: -f3`"
sum="`echo $sum | tr ' ' '+'`"
sum="$[$sum]"
echo $sum

:wq存盤退出,執行腳本:

blob.png

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

     vi /root/bin/sumspace.sh

#!/bin/bash
A=`grep "^$" $1 | wc -l`
B=`grep "^$" $2 | wc -l`
C=$[A+B]
echo "space is $C個"

:wq存盤退出,執行腳本

blob.png

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

       vi /root/bin/sumfile.sh

#!/bin/bash
etcnum=`ls -d /etc/*|wc -l`
varnum=`ls -d /var/*|wc -l`
usrnum=`ls -d /usr/*|wc -l`
echo "the totalfile is $[etcnum+varnum+usrnum]"

:wq存盤退出,執行腳本:

blob.png


邏輯運算

  true, false

         1, 0

    與:只有1與1為1,其余的都是0

         1 與 1 = 1

         1 與 0 = 0

         0  與 1 = 0

         0 與 0 = 0

    或:0或0位0,其余的都是1

         1 或 1 = 1

         1 或 0 = 1

         0 或 1 = 1

         0 或 0 = 0

    非:!比較好理解

          ! 1 = 0   非1為0

          ! 0 = 1   非0為1

 短路運算

     短路與:

         第一個為0 ,結果必定為0; ;

         第一個為1 ,第二個必須要參與運算;

    短路或

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

        第一個為0 ,第二個必須要參與運算;

 異或:^

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

聚集命令

    有兩種聚集命令的方法:

         復合式:date; who | wc -l

                   命令會一個接一個地運行

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

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

退出狀態及退出碼

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

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

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

       例如:

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

          $ echo $?

blob.png

         成功為零,失敗為1-255

    bash 自定義退出狀態碼

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

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

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

條件測試

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

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

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

          ? 若真,則返回0

          ? 若假,則返回1

       測試命令:

          ? test EXPRESSION

          ? [ EXPRESSION ]

          ? [[ EXPRESSION ]]

注意:EXPRESSION前后必須有空白字符

條件性的執行操作符

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

             ? && 代表條件性的AND THEN

             ? || 代表條件性的OR ELSE

        例如:

             $ grep -q no_such_user /etc/passwd \

             || echo 'No such user'

             No such user

blob.png

             $ ping -c1 -W2 station1 &> /dev/null \

             > && echo "station1 is up" \

             > || (echo 'station1 is unreachable'; exit 1)

             station1 is up

blob.png

bash的測試類型:

            數值測試

                       -gt: 是否大于;

                       -ge: 是否大于等于;

                       -eq: 是否等于;

                       -ne: 是否不等于;

                       -lt: 是否小于;

                       -le: 是否小于等于;

blob.png

 字符串測試

         == :是否等于;

         >: ascii 碼是否大于ascii碼 碼

         <: 是否小于

         !=: 是否不等于

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

   注意: 此表達式一般用于[[ ]] 中;

        -z "STRING" :字符串是否為空,空為真,不空為假

        -n "STRING" :字符串是否不空,不空為真,空為假

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



練習

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

vi /root/bin/argsnum

#!/bin/bash
[ $# -ge 1 ] && echo "The file's blank lines is: `grep -c '^[[:space:]]*$' $1`"
 || echo 'Atleast one argument

:wq存盤退出,執行腳本

blob.png

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

vi /root/bin/hostping.sh

#!/bin/bash
ping -c1 -W1 $1 &> /dev/null && echo "該ip地址可訪問" || echo "該ip地址不可訪問"

:wq存盤退出,執行腳本

blob.png



文件測試:

   存在性測試

          -a FILE :同-e

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

    存在性及類別測試

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

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

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

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

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

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

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

    文件權限測試

           -r FILE:是否存在且可讀

           -w FILE: 是否存在且可寫

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

    文件特殊權限測試

           -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;

原創文章,作者:舊城以西,如若轉載,請注明出處:http://www.www58058.com/34247

(0)
舊城以西舊城以西
上一篇 2016-08-15
下一篇 2016-08-15

相關推薦

  • 第二周作業

    linux 文件管理命令 rm、mv、cp rm rm命令:remove rm [OPTION]… FILE… 常用選項: -i:interactive (默認rm是‘rm -i’的別名) -f:force -r: recursive        &nb…

    Linux干貨 2016-12-08
  • 馬哥教育網絡班20期+第2周課程練習

    開啟我的博客之行 艱難的學習了一周,現在來寫寫作業回顧一下,這周我都學習了什么? 1、Linux上的文件管理類命令都有哪些,其常用的使用方法及其相關示例演示。 文件管理命令有:cp、mv、rm    復制命令:cp       cp [OPTION]… [-T] SOURCE DEST &nbsp…

    Linux干貨 2016-06-23
  • HAproxy reload config file with uninterrupt session

    HAProxy is a high performance load balancer. It is very light-weight, and free, making it a great option if you are in the market for a load balancer and need to keep your cos…

    Linux干貨 2015-04-03
  • Linux Basic–磁盤分區

    附件: 磁盤管理相關方法.pdf

    Linux干貨 2016-11-21
  • 簡單的啟動排錯

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

    Linux干貨 2016-11-26
  • 2016年8月11號學習博客

    shell腳本編程 shell腳本是包含一些命令或聲明,并符合一定格式的文本文件 shell腳本的用途有: 自動化常用命令 執行系統管理和故障排除 創建簡單的應用程序 處理文本或文件 命令查詢過程:別名–>內部變量–>hash–>$PATH ~]#bash -n 檢測腳本語法錯誤 ~]#bash -x 順…

    Linux干貨 2016-08-15
欧美性久久久久