shell 腳本編程基礎

Shell腳本簡介:

Shell腳本是一種特殊的程序,它是用戶與linux系統內核之間的一個接口,shell是一個工具程序,在用戶登錄后系統啟動。它解釋并運行由命令行或腳本文件輸入的命令,從而實現用戶與內核間的交互。

Shell腳本:也就是用各類命令預先放入到一個文件中,方便一次性執行的一個程序文件,主要是方便管理員進行設置或者管理用的,是利用shell的功能所寫的一個程序,這個程序是使用純文本文件,將一些shell的語法與指令寫在里面,然后用正規表示法,管道命令以及數據流重導向等功能,以達到我們所想要的處理目的

 

程序:指令+ 數據

程序編程風格:

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

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

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

程序的執行方式:

 計算機:運行二進制指令;

編程語言:

低級:匯編

高級:

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

java,C#

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

shell, perl, python

編程邏輯處理方式:

順序執行

循環執行

選擇執行

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

編程語言的基本結構:

數據存儲:變量、數組

表達式: a + b

語句:if

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

本文件

格式要求:首行shebang 機制

#!/bin/bash

#!/usr/bin/python

#!/usr/bin/perl

shell 腳本的用途有:

         自動化常用命令

         執行系統管理和故障排除

         創建簡單的應用程序

         處理文本或文件

創建shell腳本

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

第一行必須包括shell 聲明序列:#!(要頂格寫)

#!/bin/bash

添加注釋

注釋以# 開頭

第二步:運行腳本

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

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

可以是用:bash 腳本名稱 

        這種用法是再打開一個子shell,在子shell中運行,不對當前環境改變

       source 腳本名稱

       . 腳本名稱

        source 和.一樣,會對當前的環境改變

腳本的調試:

    bash -n /path/to/some_script

檢測腳本中的語法錯誤

bash -x /path/to/some_script

調試執行

 

變量:

  變量:命名的內存空間

數據存儲方式:

字符:

數值:整型,浮點型

  變量類型

作用:

1 、數據存儲格式

2 、參與的運算

3 、表示的數據范圍

類型:

字符

數值:整型、浮點型

編程程序語言分類:

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

java,python

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

bash  不支持浮點數

變量命名法則:

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

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

3 、見名知義

4 、統一命名Shell腳本包括一些命令或聲明,并符合一個格式的文件

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型號,內存大小,硬盤大小。

腳本:

                                                 system腳本.png

 

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

腳本:

backup腳本.png

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

 

disk.sh腳本.png

 

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

腳本:

links.sh腳本.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."   

算術運算

        bash 中的算術運算:help let

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

實現算術運算:

(1) let var= 算術表達式

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

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

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

(5) declare i var =  數值

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

(7) seq -s + 數值 數值 :計算兩個數值之間的所有數的和

(8) scale 命令可以幾位保留精度

  scale=2 表示保留兩位精度(只對除法、取余、乘冪有效)

 例如:保留兩位精度,echo "scale=2;111/22;" |bc  或者

              bc <<< "scale=2;111/22;"

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

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

echo $[$RANDOM%50]  0-49

賦值

      增強型賦值:

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

   let var OPER value

例如:let count+=3

自加3 后自賦值

自增,自減:

let var+=1  每次自加1

let var++  每次自加1

let var-=1  每次自減1

let var—  每次自減1

 

舉例演示:

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

腳本:

sumid.sh腳本.png

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

腳本:

sumspace.sh腳本.png

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

腳本:

sumfile.sh腳本.png

邏輯運算

   true, false

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

短路或

第一個為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 $?

退出狀態碼

           bash 自定義退出狀態碼

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

注意:腳本中一旦遇到exit 命令,腳本會立即終止;終止退出

狀態取決于exit 命令后面的數字

注意:如果未給腳本指定退出狀態碼,整個腳本的退出狀態碼

取決于腳本中執行的最后一條命令的狀態碼

條件測試

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

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

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

若真,則返回0

若假,則返回1

測試命令:

test EXPRESSIO

[ EXPRESSION ]

[[ EXPRESSION ]]

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

條件性的執行操作符

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

&&  代表條件性的AND THEN

|| 代表條件性的OR ELSE

Bash的測試類型

         數值測試:

-gt:  是否大于;

-ge:  是否大于等于;

-eq:  是否等于;

-ne:  是否不等于;

 

-lt:  是否小于;

-le:  是否小于等于

         字符串測試:

== :是否等于;

>: ascii 碼是否大于ascii

<:  是否小于

!=:  是否不等于

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

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

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

-n "STRING" :字符串是否不空,不空為真,空為假 (要用雙中括號‘[[]]’)

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

 

舉例演示:

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

腳本:

argsum.sh腳本.png

 

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

腳本:

hostping2.sh腳本.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

組合測試條件

          第一種方式:

COMMAND1 && COMMAND2  并且

COMMAND1 || COMMAND2  或者

! COMMAND

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

第二種方式:

EXPRESSION1 -a EXPRESSION2  并且

EXPRESSION1 -o EXPRESSION2  或者

! EXPRESSION

必須使用測試命令進行

舉例演示:

1 、chmod -rw /tmp/file1 ,編寫腳本/root/bin/per.sh,判斷當前用戶對/tmp/fiile1文件  是否不可讀且不可寫

腳本:

per2.sh腳本.png

 

2 、編寫腳本/root/bin/nologin.sh login.sh, 實現禁止和允許普通用戶登錄系統

腳本:

 禁止登錄:

nologin.sh腳本.png

 

允許登錄:

login.sh腳本.png

 

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

-p 指定要顯示的提示

-t TIMEOUT

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

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

read -p “Enter a filename: “ FILE

流程控制

        過程式編程語言:

順序執行

選擇執行

循環執行

條件選擇if語句

         選擇執行:

注意 if 語句可 嵌套

單分支

if  判斷條件:then

條件為真的分支代碼

fi

雙分支

if  判斷條件; then

條件為真的分支代碼

else

條件為假的分支代碼

fi

           多分支

if  CONDITION1 ; then

if-true

elif CONDITION2 ; then

if-ture

elif CONDITION3 ; then

if-ture

else

all-false

fi

逐條 件進行判斷,第一次遇為“真”條件時,執行其分支,而后 結束整個if 語句

條件判斷:case語句

          case 變量引用 in

PAT1)

分支1

;;

PAT2)

分支2

;;

*)

默認分支

;;

esac

     case 支持glob 風格的通配符:

*:  任意長度任意字符

?:  任意單個字符

[] :指定范圍內的任意單個字符

a|b: ab

舉例演示:

1 、寫一個腳本/root/bin/createuser.sh ,實現如下功能:使用一個用戶名做為參數,如果指定參數的用戶存在,就顯示其存在,否則添加之;顯示添加的用戶的id 號等信息

腳本:

createuser.sh腳本.png

2 、寫一個腳本/root/bin/yesorno.sh ,提示用戶輸入yes no, 并判斷用戶輸入的是yes 還是no, 或是其它信息

腳本:

yesorno.sh腳本.png

3 、寫一個腳本/root/bin/filetype.sh, 判斷用戶輸入文件路徑,顯示其文件類型(普通,目錄,鏈接,其它文件類型)

腳本:

filetype.sh腳本.png

4 、寫一個腳本/root/bin/checkint.sh, 判斷用戶輸入的參數是否為正整數

腳本:

checkint.sh腳本.png

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

滿

腳本:

diskinode.sh腳本.png

 

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

sh.sh腳本.png

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

腳本:

iphefa.sh腳本.png

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

腳本:

1..100.sh腳本.png

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

腳本:

A+B=.sh腳本.png

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

(0)
ZJMZJM
上一篇 2016-08-21 20:42
下一篇 2016-08-21 20:45

相關推薦

  • 推薦-File System manager

    文件系統(File system) :     文件系統概要    文件系統的分類    文件系統的管理工具             mkfs btrfs ext xfs&nbsp…

    Linux干貨 2016-03-26
  • 關于軟件包管理

            軟件包管理 CentOS系統上使用rpm命令管理程序包 安裝、卸載、升級、查詢、檢驗、數據庫維護 rpm安裝:         rpm {-i|–install} [安裝-選項] 打包;包         -h …

    系統運維 2016-08-30
  • Linux中find常見用法示例

    ·find   path   -option   [   -print ]   [ -exec   -ok   command ]   {} \; find命令的參數; pathname: find命…

    Linux干貨 2017-04-18
  • 第二周(8.15-8.21)博客作業

    1、Linux上的文件管理類命令都有哪些,其常用的使用方法及其相關示例演示。 #touch 如果a.txt不存在,生成一個新的空文檔a.txt。如果a.txt存在,那么只更改該文檔的時間信息 #ls  是list的簡寫,列出當前目錄下的所有文件名 #cp a.txt b.txt  cp是copy的簡寫,用來復制文件。在工作目錄下,將a.t…

    Linux干貨 2016-08-24
  • N24 W3 博客作業

    第三周 "   1、列出當前系統上所有已經登錄的用戶的用戶名,注意:同一個用戶登錄多次,則只顯示一次即可。 [root@localhost ~]# who | cut –d’ ‘ –f1 | uniq 2、取出最后登錄到當前系統的用戶的相關信息。 [root@localhost ~]# id `who | tail -n 1 | cut …

    Linux干貨 2016-11-14
  • 馬哥教育網絡班21期+第四周課程練習

    1、復制/etc/skel目錄為/home/tuser1,要求/home/tuser1及其內部文件的屬組和其它用戶均沒有任何訪問權限。 ~]# cp -r /etc/skel /home/tuser1; chmod -R gx=— /home/tuser1 [root@mag…

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