Shell腳本編程入門

認識Shell

Shell原意為貝殼

Linux系統中的shell是一個特殊的應用程序,它介于操作系統內核與用戶之間,充當一個命令解釋器的角色,負責接收用戶輸入的操作指令(命令)并進行解釋,將需要執行的操作傳遞給內核執行,并輸出執行結果。

可以使用命令查看當前使用的是哪種shell以及當前Linux系統中都支持哪些shell種類。

 

查看當前系統使用的shell

Shell腳本編程入門

 

查看當前Linux系統所支持的shell種類

Shell腳本編程入門

其中/bin/bash是目前大多數Linux版本采用的默認shell。Bash的全稱為Bourne Again Shell,是最受歡迎的開源軟件項目之一。

常見的shell解釋器程序有很多種,使用不同的shell時,其內部指令、命令行提示等方面會存在一些區別。

 

Shell腳本

只要將平時使用的各種Linux命令按順序保存到一個文本文件,然后添加可執行權限,這個文件就成為一個shell腳本了。

編寫一個恰到好處的shell腳本程序,可以批量處理、自動化地完成一系列維護任務、大大減輕管理員的負擔。

周期性的任務可以通過Crond服務來管理,而步驟復雜、操作繁瑣的任務可以使用Shell腳本來批量處理,兩相結合就可以非常靈活、自主地完成各種系統運維工作。Shell腳本負責具體的備份操作,Crond服務負責控制備份周期。

 

1、腳本的編寫

Shell腳本編程入門

Shell腳本主要由開頭部分、注釋部分以及語句部分組成

1)開頭

“#!/bin/bash”是一行特殊的腳本聲明,表示此行以后的語句通過/bin/bash程序來解釋執行。

符號“#!”用來告訴系統它后面的參數是用來執行該文件的程序。

2)注釋

其它以”#”開頭的語句表示注釋信息,建議在程序中使用注釋,即使過了長時間也能很快的了解腳本的用途。

3)語句

Linux各種命令的集合

 

2、腳本的執行

編寫完成shell腳本后,需要賦予執行權限

Shell腳本編程入門

執行此腳本文件后,輸出結果與依次執行這兩條命令是相同的,從而實現了批量處理的自動化過程。

Linux還提供了執行shell腳本的方式——指定某個shell來解釋腳本語句,或者通過內部命令source(或點號”.”)來加載文件的源代碼執行。

例如,使用”sh first.sh”“. first.sh”都可以執行firsh.sh腳本中的語句。

Shell腳本編程入門

注意:以上三種執行方式不添加執行權限也可以執行文件

 

3、腳本調試

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

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

 

Shell變量

Shell變量用來存放系統和用戶需要使用的特定參數(值)。而且這些參數可以根據用戶的設定或系統環境的變化而相應變化。

常見的Shell變量的類型包括自定義變量、環境變量、預定義變量、位置變量。

1、自定義變量

自定義變量是由系統用戶自己定義的變量,只在用戶自己的Shell環境中有效,因此又稱為本地變量。

 

1)定義新的變量

定義變量的基本格式為變量名=變量值,等號兩邊沒有空格。

[root@localhost ~]# name=tom

[root@localhost ~]# age=20

Shell腳本編程入門

 

變量名稱命名規則:

a.不能使程序中的保留字:例如if, for

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

c.見名知義

d.統一命名規則:駝峰命名法

 

2)查看和引用變量的值

Shell腳本編程入門

 

2、環境變量

環境變量指的是出于運行需要而由Linux系統提前創建的一類變量,主要用于設置用戶的工作環境,包括用戶宿主目錄、命令替換路徑、用戶當前目錄、登錄終端等。環境變量的值由linux系統自動維護,會隨著用戶狀態的改變而改變。

使用env命令可以查看當前工作環境下的環境變量,對于常見的一些環境變量應了解其各自的用途。

例如USER表示用戶標識、HOME表示用戶的宿主目錄、LANG表示語言和字符集、PWD表示當前所在的工作目錄、PATH表示命令搜索路徑….

 

查看當前Linux系統中所有的環境變量

   blob.png

可以用命令修改環境變量的搜索路徑,這樣寫完shell腳本以后可以直接輸入腳本名稱直接執行,不用每次輸入文件的路徑。

 

臨時修改:只對當前終端有效

Shell腳本編程入門

 

永久修改:永久有效

修改家目錄下的隱藏文件.bash_profile,添加指定的搜索路徑即可,搜索路徑之間用“:”分隔,添加完成后需要重新讀取該配置文件讓其生效。

Shell腳本編程入門

 

重新讀取配置文件使其立即生效

Shell腳本編程入門

Shell腳本編程入門

 

將搜索路徑添加完成后直接輸入文件名即可運行成功

Shell腳本編程入門

 

PATH的搜索順序:從左到右依次搜索,

Shell腳本編程入門

同樣在/usr/bin下面寫一個同名的腳本文件,執行時依然執行/testdir/script目錄下的文件,當把hash緩存清空后,即執行了/usr/bin目錄下的first.sh文件,如果把緩存再次清空,執行腳本文件報錯,清空緩存后,有可以執行了。

從此可見,緩存(hash)中的命令優先于搜索路徑,如果緩存中有這條命令,就不去搜索PATH變量,文件不存在也執行hash,會報錯;清空緩存后,按照PATH變量的搜索順序依次查找,當PATH變量有多個可以匹配,執行先匹配到,匹配到第一個腳本時不再往下搜索。

 

環境變量的配置文件

全局配置文件:/etc/.bash_profile

個人配置文件:~/.bash_profile

 

3、預定義變量

預定義變量是由Bash程序預先定義好的一類特殊變量,用戶只能使用預定義變量,而不能創建新的預定義變量,也不能直接為預定義變量賦值。預定義變量使用$符號和另一個符號組合表示,較常用的幾個預定義變量如下:

$#:表示命令行中位置參數的個數。

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

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

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

$?:表示前一條命令執行后的返回狀態,0表示成功,非0表示失敗。

$0:表示當前執行的腳本或程序的名稱。

 

示例:備份目錄數據,并顯示備份信息

Shell腳本編程入門

 

4、位置變量

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

當執行命令行操作時,第一個字符表示命令名或腳本程序名,其余的字符串參數按照從左到右的順序依次賦值給位置變量。

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

 

示例:計算兩個數值的和

Shell腳本編程入門

 

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

Shell腳本編程入門

 

   定義只讀變量

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

readonly name

declare -r name

 

示例:定義只讀變量

Shell腳本編程入門

注意:只讀變量同樣只在當前終端中有效

 

變量賦值的特殊操作

1)雙引號(

雙引號主要起了一個界定字符串的作用,特別是當要賦值的內容中包含空格時,必須以雙引號括起來,否則會報錯;其他情況下雙引號通??梢允÷浴?/span>

Shell腳本編程入門

在雙引號范圍內,使用“$”符號可以引用其他變量的值(變量引用),從而能夠直接調用現有變量的值來賦值給新的變量。

Shell腳本編程入門

Shell腳本編程入門

2)單引號(

當要賦值的內容中包含$、 \等具有特殊含義的字符時,應使用單引號括起來。在單引號的范圍內,將無法引用其他變量的值,任何字符均作為普通字符看待。但賦值內容中包含單引號時,需使用“\’”符號進行轉義,以免沖突。

Shell腳本編程入門

 

3)反撇號(`

反撇號主要用于命令替換,允許將執行某個命令的屏幕輸出結果賦值給變量。反撇號括起來的范圍內必須是能夠執行的命令行,否則將會出錯。

Shell腳本編程入門

需要注意的是,使用反撇號難以在一行命令中實現嵌套命令替換操作,這時可以改用“$()”來代替反撇號操作,以解決嵌套的問題。

Shell腳本編程入門

 

變量的作用范圍

1、設置局部變量

默認情況下,新定義的變量只在當前的Shell環境中有效,因此成為局部變量。當進入子程序或新的子Shell環境時,局部變量將無法再使用。

Shell腳本編程入門

 

2、設置全局變量

為了使用戶定義的變量在所有的子Shell環境中能夠繼續使用,減少重復設置工作,可以通過內部命令export將指定的變量導出為全局變量可以同時制定多個變量名稱作為參數(不需使用$符合),變量名之間以空格分隔。

Shell腳本編程入門

 

使用export導出全局變量的同時,也可以為變量進行賦值,這樣在新定義全局變量時就不需要提前進行賦值了,也可以將之前的局部變量設置使用export命令設置為全局變量,使其在子shell中可以調用。

Shell腳本編程入門

注意:設置全局變量后,子進程可以調用父進程的變量,反之則不可以。

 

條件測試

使用專門的測試工具test命令,可以對特定條件進行測試,并根據返回值來判斷條件是否成立(返回值0表示條件成立)。

test 條件表達式

[ 條件表達式 ]

 

兩種方式作用完全相同,但后者更為常用,也更貼近編程習慣。需要注意的是,方括號與表達式之間需要至少一個空格進行分割。

根據需要測試的條件類別不同,條件表達式也不一樣。比較常用的條件操作包括文件測試、整數值比較、字符串比較,以及針對多個條件的邏輯測試。

執行條件測試操作后,通過預定義變量”$?“可以獲得測試命令的返回狀態值,從而判斷該條件是否成立。echo $?查看返回狀態值。

 

1、文件測試

    存在性測試

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

    -a FILE:同-e

     

    存在性及類別測試

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

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

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

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

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

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

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

     

    文件權限測試

    -r  測試當前用戶是否有權限讀?。?/span>Read

    -w         測試當前用戶是否有權限寫入(Write

    -x 測試是否這只有可執行權限(Excute

     

    文件特殊權限測試

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

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

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

     

    文件大小測試

    -s FILE: 是否存在且非空;

     

    文件是否打開

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

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

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

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

     

    雙目測試

    FILE1 -ef FILE2: FILE1FILE2是否指向同一個設備上的相同inode

    FILE1 -nt FILE2: FILE1是否新于FILE2

    FILE1 -ot FILE2: FILE1是否舊于FILE2

 

2、數值比較

-eq   1個數等于(Equal)第2個數

-ne   1個數不等于(Not Equal)第2個數

-gt    1個數大于(Greater Than)第2個數

-lt    1個數小于(Lesser Than)第2個數

-le     1個數小于或等于(Lesser or Equal)第2個數

-ge  1個數大于或等于(Lesser or Equal)第2個數

 

3、字符串比較

=     1個字符串與第2個字符串相同

!=    1個字符串與第2個字符串相同,其中!符號表示取反的意思

-z    檢查字符串是否為空(Zero),對于未定義或賦予空值的變量將視為空串。

==    是否等于;

>:      ascii碼是否大于ascii

<:      是否小于

!=:     是否不等于

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

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

 

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

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

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

 

算術運算

bash中的算術運算

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

實現算術運算:

let var=算術表達式

var=$[算術表達式]

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

var=$(expr arg1 arg2 arg3 …)

declare –i var = 數值

echo ‘算術表達式’ | bc

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

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

echo $[$RANDOM%50] 0-49之間隨機數

Shell腳本編程入門

 

賦值

增強型賦值:

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

let varOPERvalue

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

自增,自減:

let var+=1

let var++

let var-=1

let var–

 

示例:算術運算

Shell腳本編程入門

 

示例:j自增自減運算

Shell腳本編程入門

 

    邏輯測試

&&:邏輯與,表示而且的意思,只有當前后兩個條件都成立時,真個測試命令的返回值才為0。使用test命令測試時,&&可改為-a。

||:邏輯與,表示或者的意思,只有前后兩個條件有一個成立時,整個測試命令的返回值為0。使用test名測試時,||可改為-o。

!:邏輯否,表示的意思,只有當指定的條件不成立時,正測試命令的返回值才為0

 

邏輯運算

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

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

 

組合測試條件

第一種方式:

COMMAND1 && COMMAND2 并且

COMMAND1 || COMMAND2 或者

! COMMAND

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

第二種方式:

EXPRESSION1 -a EXPRESSION2 并且

EXPRESSION1 -o EXPRESSION2 或者

! EXPRESSION

必須使用測試命令進行;

# [ -z “$HOSTNAME” -o $HOSTNAME "==\"localhost.localdomain" ] && hostname www.magedu.com

# [ -f /bin/cat -a -x /bin/cat ] && cat /etc/fstab

 

示例:判斷兩個變量的大小

Shell腳本編程入門

 

退出狀態

進程使用退出狀態來報告成功或失敗,$? 變量保存最近的命令退出狀態

0  代表成功

1255  代表失敗

 

示例:ping一個ip地址,并查看其返回

Shell腳本編程入門

 

退出狀態碼

bash自定義退出狀態碼

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

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

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

 

示例:根據測試條件返回狀態碼

Shell腳本編程入門

 

read命令:接受用戶輸入

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

read  [選項]  [參數]

-p    指定要顯示的提示信息

-t    指定讀取值時等待的時間(秒)

-n    讀取用戶輸入的前幾個字符

-s    隱藏用戶的輸入字符

-r    允許輸入包含反斜杠

-d    -d選項指定的字符作為結束符,如空格、特殊符號

read 從標準輸入中讀取值,給每個單詞分配一個變量,所有剩余單詞都被分配給最后一個變量。

read -p “Enter a filename: “ FILE

 

示例:編寫修改當前用戶的密碼腳本

Shell腳本編程入門

使用-s選項可隱藏用戶要輸入的字符信息,如密碼等信息

 

 

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

(0)
cyh5217cyh5217
上一篇 2016-08-12
下一篇 2016-08-12

相關推薦

  • LNAMP 跨網段實現

    感謝Kason老師給我了知識!

    2017-12-31
  • Linux系統的終端類型

    Linux系統的終端類型    Linux系統的終端主要包括控制臺終端、控制終端、串口終端、偽終端、虛擬終端。 1.  控制臺終端(/dev/console)。    在Unix系統中,計算機顯示器通常被稱為控制臺終端。Console與虛擬終端相關聯,內核將信息送到控制臺終端上(/dev/conso…

    Linux干貨 2015-09-14
  • httpd功能配置之虛擬主機

       apache默認使用80端口提供服務,使用主服務器配置的話,一臺物理機只能提供一個站點服務;可以使用虛擬主機方式提供不同的訪問,以實現一臺主機提供多站點服務。    虛擬主機的實現方式有三種:基于端口、基于IP、基于主機名。    一、基于端口的虛擬主機     &nbsp…

    Linux干貨 2016-03-12
  • http狀態碼大全

    狀態值:100 客戶端應當繼續發送請求。這個臨時響應是用來通知客戶端它的部分請求已經被服務器接收,且仍未被拒絕??蛻舳藨斃^續發送請求的剩余部分,或者如果請求已經完成,忽略這個響應。服務器必須在請求完成后向客戶端發送一個最終響應。 狀態值:101 服務器已經理解了客戶端的請求,并將通過Upgrade 消息頭通知客戶端采用不同的協議來完成這個請求。在發送完這個…

    Linux干貨 2016-11-01
  • 第4周作業

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

    Linux干貨 2016-12-25

評論列表(1條)

  • 馬哥教育
    馬哥教育 2016-08-12 14:39

    學習態度端正,博客不僅寫的完善而且有自己的想法,通過自己的思路匯總,足以見其對知識的理解深刻,望后期能持續學習,提升自我。

欧美性久久久久