學習shell script

摘要:概述、script的編寫、test命令、[]判斷符號、默認變量($1...)、if...then條件判斷式、正則表達式

1、概述shell

【什麼是shell script】bash

針對shell所寫的腳本,將多個命令彙整起來一塊兒執行網絡

能夠進行相似程序的編寫,而且不須要通過編譯就可以執行less

利用shell的功能所寫的一個「程序」,這個程序是使用純文本文件,將一些shell的語法與命令寫在裏面,搭配正則表達式、管道命令與數據流重定向等功能,以達到咱們所想要的處理目的。ide

【用途】函數

簡化咱們平常的工做管理oop

一些服務的啓動都是經過shell script進行的測試

 

2、編寫第一個Hello world程序this

【預處理】

新建一個script文件:vi helloworld.sh

【代碼】

1 #!bin/bash
2 # Program:
3 #       This is my first script.
4 # History:
5 # 2017-9-30 liuyu First release
6 
7 echo "Hello World!"
8 exit 0
View Code

說明:

#!bin/bash:聲明這個script使用的shell名稱

聲明這個文件內是使用bash的語法,即這個程序被執行時,它就可以加載bash的相關環境配置文件(通常來講就是non-login shell的~/.bashrc),而且執行bash使咱們下面的命名可以執行。

exit 0:告知執行結果

咱們能夠利用exit這個命令來讓程序中斷,而且回傳一個數值給系統。如「exit 0」表明離開script而且回傳一個0給系統,即咱們執行完這個script後,若接着執行echo $?則可獲得0的值。

【執行script程序】

bash 文件名

 

3、簡單的shell script練習

1. 交互式腳本:變量內容由用戶決定

題目:請你以read命令的用途,編寫一個script,它可讓用戶輸入firstname與lastname,最後而且在屏幕上顯示「Your full name is: 」的內容。

 1 #!bin/bash
 2 # Program:
 3 #       an easy interactive program
 4 # History:
 5 # 2017-9-30 liuyu First release
 6 
 7 
 8 read -p "Please input your firstname: " firstname
 9 read -p "please input your lastname: " lastname
10 echo "Your full name is $firstname $lastname!"
View Code

2. 把日期做文件名:利用日期進行文件的建立

題目:我但願將天天的數據備份在不一樣的文件裏,因此就須要以天天的日期做爲文件名。關鍵是日期怎麼來!假設我要建立3個空的文件,文件名最開頭由用戶決定(咱們假設是filename),那今天的日期是2017/9/30,我想之前天、昨天、今天的日期來建立這些文件,即filename20170928, filename20170929, dilename20170930,該如何是好?

 1 #!bin/bash
 2 # Program:
 3 #       filename is created by user's input.
 4 # History:
 5 # 2017-9-30 liuyu First release
 6 
 7 echo "I will use 'touch' to create three files."
 8 read -p "Please input your filename: " fileuser
 9 
10 #開始判斷有否配置文件名,防止用戶隨意按[Enter],咱們默認開頭爲filename
11 filename=${fileuser:-"filename"}
12 
13 date1=$(date --date='2 days ago' +%Y%m%d) #前兩天的日期
14 date2=$(date --date='1 days ago' +%Y%m%d)
15 date3=$(date +%Y%m%d)                   #今天的日期
16 file1=${filename}${date1}       #追加的方式配置文件名
17 file2=${filename}${date2}
18 file3=${filename}${date3}
19 
20 touch "$file1"  #防止有空格
21 touch "$file2"
22 touch "$file3"
View Code

說明:此程序運用了許多bash中的變量知識,因此學好shell才能輕鬆地編寫script!

3. 數值運算:簡單的加減乘除

題目:讓用戶輸入兩個整數,而後計算出這兩個數相乘的結果。

 1 #!bin/bash
 2 # Program:
 3 #       multiply two integer.
 4 # History:
 5 # liuyu 2017-9-30 First release
 6 
 7 echo "You should input 2 integers,i will cross them!"
 8 read -p "first number: " firnum
 9 read -p "second number: " secnum
10 total=$(($firnum*$secnum))
11 echo "The result of $firnum*$secnum is $total."
View Code

 

4、test命令的測試功能

1. 功能

檢測系統上面某些文件、測試文件的相關屬性。

2. 經常使用命令

命令 意義
test -e filename 該文件名是否存在
test -f filename 該文件名是否存在且爲文件
test -e filename 該文件名是否存在且爲目錄
test -S filename 該文件名是否存在且爲一個Socket文件
test -L filename 該文件名是否存在且爲一個鏈接文件
test -r filename 該文件名是否存在且具備「可讀」的權限
test -w filename 該文件名是否存在且具備「可寫」的權限
test -x filename 該文件名是否存在且具備「可執行」的權限
test file1 -nt file2  判斷file1是否比file2新
test file1 -ef file2 判斷file1與file2是否爲同一個文件,主要用於hard link
test n1 -eq n2 兩數值相等
test n1 -gt n2 n1大於n2
test n1 -lt n2 n1小於n2
test n1 -ge n2 n1大於等於n2
test n1 -le n2 n1小於等於n2
test -z string 判斷是否爲空字符串,如果,返回true
test str1=str2  判斷str1是否等於str2
-a 兩個條件同時成立,如test -r file -a -x file,則file同時具備r與x權限時,纔回傳true
-o 任何一個條件成立,如test -r file -o -x file,則file具備r或x權限時,就可回傳true
! 反向狀態,如test ! -x file,當file不具備x時,纔回傳true

3. 示例

題目:寫一個script,讓用戶輸入一個文件名,要求進行下面的判斷:

這個文件是否存在,若不存在則給予一個「Filename does not exist」的信息,並中斷程序;

若這個文件存在,則判斷它是個目錄或文件,結果輸出「Filename is regular file」或「Filename is directory」;

判斷一下,執行者的身份對這個文件或目錄所擁有的權限,並輸出權限數據。

 1 #!bin/bash
 2 # Program:
 3 #       A script which covers the using of test.
 4 # History:
 5 # 2017-9-30 liuyu First release
 6 
 7 echo "Please input a filename, I will check the filename's type and permission."
 8 read -p "Input a filename: " filename
 9 test -z $filename && echo "You must input a filename." && exit 0
10 
11 test ! -e $filename && echo "The filename '$filename' DO NOT exist" && exit 0
12 
13 test -f $filename && filetype="regular file"
14 test -d $filename && filetype="directory"
15 test -r $filename && perm="readable"
16 test -w $filename && perm="writable"
17 test -x $filename && perm="executable"
18 
19 echo "The filename: $filename is a $filetype"
20 echo "And the permissions are : $perm"
View Code

 

5、判斷符號[]的使用

1. 功能

數據的判斷、字符串判別

2. 用法

命令 意義
[ -z "$HOME" ] 判斷HOME變量是否爲空
[ "$HOME" == "$var" ] 判斷兩個變量是否相等
[ "$HOME" == "string" ] 判斷變量的內容是否爲string

 

 

 

 

 

 

 

3. 示例

題目:寫一個script,要求以下:

當執行一個程序的時候,這個程序會讓用戶選擇Y或N;

若是用戶輸入Y或y時,就顯示「OK, continue」;

若是用戶輸入N或n時,就顯示「Oh, interrupt!」;

若是不是Y/y/N/n以內的其餘字符,就顯示「I don't know what your choice is」。

 1 #!/bin/bash
 2 # Program:
 3 #       A practice with [].
 4 # History:
 5 # 2017-9-30 liuyu First release
 6 
 7 read -p "Please input (Y/N): " yn
 8 [ "$yn" == "Y" -o "$yn" == "y" ] && echo "OK, continue" && exit 0
 9 [ "$yn" == "N" -o "$yn" == "n" ] && echo "Oh, interrupt!" && exit 0
10 echo "I don't know what your choice is." && exit 0
View Code

 

6、默認變量($0,$1...)

1. 概述

咱們知道命令能夠帶有參數,而咱們還須要知道的是shell script也能夠在腳本文件名後面帶有參數。(注意!必定是script文件喔!)

2. 示例

題目:從新啓動系統註冊表文件

命令:/etc/init.d/syslog restart

評講:此命令能夠從新啓動/etc/init.d/syslog這個程序

題目:承上,關閉該服務

命令:/etc/init.d/syslog stop

3. 用法

文件名 opt1 opt2 opt3 opt4

    $0      $1    $2     $3    $4

解釋:執行的腳本文件名爲$0這個變量,第一個接的參數就是$1。

補充:只要咱們在script裏面善用$1的話,就能夠很簡單地當即執行某些命令功能了!

補充:除了這些數字的變量以外,咱們還有一些較爲特殊的變量能夠在script內使用來調用這些參數。

$#:表明後接的參數「個數」

$@:表明"$1"、"$2"、"$3"、"$4"之意,每一個變量是獨立的(用雙引號括起來)

$*:表明「"$1c$2c$3c$4"」,其中c爲分隔字符,默認爲空格鍵,因此本例中表明「"$1 $2 $3 $4"」之意

4. 練習

題目:假設你要執行一個能夠帶參數的script,執行該腳本後屏幕會顯示以下的數據。

程序的文件名

共有幾個參數

若參數的個數小於2則告知用戶參數數量太少

所有的參數內容

第一個參數

第二個參數

 1 #!/bin/bash
 2 # Program:
 3 #       Default variable of shell script.
 4 # History:
 5 # 2017-10-1 liuyu First release
 6 
 7 echo "The script name is  ==> $0"
 8 echo "Total parameter number is  ==> $#"
 9 [ "$#" -lt 2 ] && echo "The number of parameter is less than 2. Stop here." && exit 0
10 echo "Your whole parameter is  ==> '$@'"
11 echo "The 1st parameter    ==> $1"
12 echo "The 2nd parameter    ==> $2"
sh07.sh

注意:參數個數就是你執行該文件時在該文件後加的參數個數,即,若你執行「bash sh07.sh」,則參數個數爲0。

5. shift:形成參數變量號碼偏移

咱們要知道的是——腳本後面所接的變量可以進行偏移。

咱們經過一個例子來講明偏移是什麼。

題目:咱們將上個文件中的內容稍做變化,用來顯示每次偏移後參數的變化狀況。

 1 #!/bin/bash
 2 # Program:
 3 #       Default variable of shell script.
 4 # History:
 5 # 2017-10-1 liuyu First release
 6 
 7 echo "Total parameter number is  ==> $#"
 8 echo "Your whole parameter is    ==> '$@'"
 9 shift           #進行第一次「一個變量的shift」
10 echo "Total parameter number is  ==> $#"
11 echo "Your whole parameter is    ==> '$@'"
12 shift 3         #進行第二次「三個變量的shift」
13 echo "Total parameter number is  ==> $#"
14 echo "Your whole parameter is    ==> '$@'"
sh08.sh

若是咱們執行「bash sh08.sh one two three four five six」,咱們會看到以下顯示:

分析:經過這個結果,咱們知道shift會移動變量,並且shift後面能夠接數字,表明拿掉最前面的幾個參數的意思。

 

注:「七/八/九」都屬於條件判斷式下的子內容。

7、條件判斷式——if...then

1. 單層判斷

【命令】

if [ 條件判斷式 ]; then

  當條件判斷式成立時,能夠進行的命令工做內容;

fi

【條件判斷式】

當有多個條件要判別時,除了能夠將多個條件寫入一箇中括號內的狀況以外,還可使用多箇中括號,而此時每一箇中括號內只寫入一個判斷式。

即[ "$yn" == "Y" -o "$yn" == "y" ] 能夠被替換爲 [ "$yn" == "Y" ] || [ "$yn" == "y" ]

【示例】

題目:將sh06.sh這個腳本修改爲爲if...then的樣式

 1 #!/bin/bash
 2 # Program:
 3 #       A practice with [].
 4 # History:
 5 # 2017-9-30 liuyu First release
 6 
 7 read -p "Please input (Y/N): " yn
 8 if [ "$yn" == "Y" ] || [ "$yn" == "y" ]; then
 9         echo "OK, continue"
10         exit 0
11 fi
12 if [ "$yn" == "N" ] || [ "$yn" == "n" ]; then
13         echo "oh, interrupt!"
14         exit 0
15 fi
16 echo "I don't know what your choice is." && exit 0
sh06-2.sh

2. 多層判斷

【命令1】

if [ 條件判斷式 ]; then

  當條件判斷式成立時,能夠進行的命令工做內容;

else

  當條件判斷式不成立時,能夠進行的命令工做內容;

fi

【命令2】

if [ 條件判斷式一 ]; then

  當條件判斷式一成立時,能夠進行的命令工做內容;

elif [ 條件判斷式二 ]; then

  當條件判斷式二成立時,能夠進行的命令工做內容;

else

  當條件判斷式一與二均不成立時,能夠進行的命令工做內容;

fi

【示例】

題目:將sh06-2.sh這個腳本修改爲爲if...elif...else的樣式

 1 #!/bin/bash
 2 # Program:
 3 #       A practice with [].
 4 # History:
 5 # 2017-9-30 liuyu First release
 6 
 7 read -p "Please input (Y/N): " yn
 8 if [ "$yn" == "Y" ] || [ "$yn" == "y" ]; then
 9         echo "OK, continue"
10 elif [ "$yn" == "N" ] || [ "$yn" == "n" ]; then
11         echo "oh, interrupt!"
12 else
13         echo "I don't know what your choice is."
14 fi
View Code

【練習】

題目:通常來講,若是你不但願用戶由鍵盤輸入額外的數據時,可使用上一節提到的參數功能($1)!讓用戶在執行命令時就將參數代進去。如今咱們想讓用戶輸入「hello」這個關鍵字時,利用參數的方法能夠這樣依序設計:①判斷$1是否爲hello,若是是的話,就顯示「Hello,how are you?」;②若是沒有加任何參數,就提示用戶必需要使用的參數;③而若是加入的參數不是hello,就提醒用戶僅能使用hello爲參數。

 1 #!/bin/bash
 2 # Program:
 3 #       Check $1 is equal to "hello"
 4 # History:
 5 # 2017-10-1 liuyu FIrst release
 6 
 7 if [ "$1" == "hello" ]; then
 8         echo "Hello,how are you?"
 9 elif [ "$1" == "" ]; then
10         echo "You must input parameters,ex> {$0 someword}"
11 else
12         echo "The only parameter is 'hello',ex> {$0 hello}"
13 fi
View Code

評講:咱們在$1的位置分別輸入hello、沒有輸入、隨意輸入,就能夠看到不一樣的輸出。

 

8、利用case...esac判斷

9、利用函數功能

 

10、循環(loop)

1. 條件循環

【while do done】

while [ condition ]    //中括號內的狀態就是判斷式

do        //循環的開始

  程序段落

done       //循環的結束

解釋:當 condition 條件成立時,就進行循環,直到 condition 的條件不成立才中止。

【until do done】

until [ condition ]

do

  程序段落

done

解釋:當 condition 條件成立時,就終止循環,不然就持續進行循環的程序段。

【練習】

題目1:假設我要讓用戶輸入yes或者是YES才結束程序的執行,不然就一直進行告知用戶輸入字符串。

 1 #!/bin/bash
 2 # Program:
 3 #       while:Repeat question until user input correct answer.
 4 # History:
 5 # 2017-10-1 liuyu First release
 6 
 7 while [ "$yn" != "yes" -a "$yn" != "YES" ]
 8 do
 9         read -p "Please input yes/YES to stop this program: " yn
10 done
11 echo "OK! you input the correct answer."
sh13.sh(while)
 1 #!/bin/bash
 2 # Program:
 3 #       until:Repeat question until user input correct answer.
 4 # History:
 5 # 2017-10-1 liuyu First release
 6 
 7 until [ "$yn" == "yes" -o "$yn" == "YES" ]
 8 do
 9         read -p "Please input yes/YES to stop this program: " yn
10 done
11 echo "OK! you input the correct answer."
sh13-2.sh(until)

題目2:計算1+2+3+...+100這個數據。

 1 #!/bin/bash
 2 # Program:
 3 #       Use loop to calculate "1+2+3+...+100" result.
 4 # History:
 5 # 2017-10-1 liuyu First release
 6 
 7 ans=0           # 這是累加的數值變量
 8 i=0             # 這是累計的數值,亦便是1,2,3...
 9 while [ "$i" != "100" ]
10 do
11         i=$(($i+1))
12         ans=$(($ans+$i))
13 done
14 echo "The result of '1+2+3+...+100' is ==> $ans"
sh14.sh

題目3:讓用戶自行輸入一個數字,讓程序由1+2+...直到用戶輸入的數字爲止。

 1 #!/bin/bash
 2 # Program:
 3 #       practice of until of page 394.
 4 # History:
 5 # 2017-10-1 liuyu First release
 6 
 7 ans=0
 8 i=0
 9 read -p "Please input a integer: " n
10 if [ "$n" -le "0" ]; then
11         echo "Sorry, you input a integer which isn't bigger than one!"
12         exit 0;
13 else
14         until [ "$i" -eq "$n" ]
15         do
16                 i=$(($i+1))
17                 ans=$(($ans+$i))
18         done
19         echo "The result of '1+2+3+...+$n' is ==> $ans"
20 fi
View Code

2. 固定循環

【for do done】

for var in con1 con2 con3 ...

do

  程序段

done

解釋:變量var的內容在第 i 次循環時爲coni

【練習】

題目1:假設我有三種動物,分別是 dog, cat, elephant 三種,我想每一行都輸出這樣:「There are dogs...」之類的字樣。

 1 #!/bin/bash
 2 # Program:
 3 #       Using for...loop to print 3 animals
 4 # History:
 5 # 2017-10-1 liuyu First release
 6 
 7 for animal in dog cat elephant
 8 do
 9         echo "There are ${animal}s..."
10 done
View Code

題目2:系統上的帳號都是寫在/etc/passwd內的第一個字段,你能不能經過管道命令 cut 找出單純的帳號名稱後,以 id 及 finger 分別檢查用戶的標識符與特殊參數呢?

 1 #!/bin/bash
 2 # Program:
 3 #       Use id,finger command to check system account's information.
 4 # History:
 5 # 2017-10-1 liuyu First release
 6 
 7 users=$(cut -d ':' -f1 /etc/passwd)
 8 for username in $users
 9 do
10         id $username
11         finger $username
12 done
View Code

評講:執行此腳本後,咱們的系統帳號就會被獲取出來檢查。

補充:這個操做還能夠用在每一個帳號的刪除/更改上面呢!

題目3:我如今須要一連串的數字來進行循環。如我想要利用 ping 這個能夠判斷網絡狀態的命令。來進行網絡狀態的實際檢測時,我想要檢測的域是本機所在的192.168.1.1~192.168.1.100,因爲有100臺主機,故我不想在 for 後面輸入1到100。

 1 #!/bin/bash
 2 # Program:
 3 #       Use ping command to check the network's PC state.
 4 # History:
 5 # 2017-10-1 liuyu First release
 6 
 7 network="192.168.1"   #先定義一個域的前面部分
 8 for sitenu in $(seq 1 100)   #seq爲sequence(連續)的縮寫之意
 9 do
10         #下面的語句取得ping的回傳值是正確的仍是失敗的
11         ping -c l -w l ${network}.${sitenu} &> /dev/null && result=0 || result=1
12         #開始回顯結果是正確的啓動(UP)仍是錯誤的沒有連通(DOWN)
13         if [ "$result" == 0 ]; then
14                 echo "Sever ${network}.${sitenu} is UP."
15         else
16                 echo "Sever ${network}.${sitenu} is DOWN."
17         fi
18 done
View Code

評講:上面這一串命令執行以後就能夠顯示出192.168.1.1~192.168.1.100共100部主機目前是否能與你的機器連通!若是你的域與咱們所在的位置不一樣,則直接修改上面那個network的變量內容便可!

題目4:讓用戶輸入某個目錄文件名,而後找出某目錄內的文件名的權限。

 1 #!/bin/bash
 2 # Program:
 3 #       User input dir name, I find the permission of files.
 4 # History:
 5 # 2017-10-1 liuyu First release
 6 
 7 # 1.先看看這個目錄是否存在
 8 read -p "Please input a directory: " dir
 9 if [ "$dir" == "" -o ! -d "$dir" ]; then
10         echo "The $dir is NOT exist in your system."
11         exit 1;
12 fi
13 
14 # 2. 開始測試文件
15 filelist=$(ls $dir)     # 列出全部在該目錄下的文件名
16 for filename in $filelist
17 do
18         perm=""
19         test -r "$dir/$filename" && perm="$perm readable"
20         test -w "$dir/$filename" && perm="$perm writable"
21         test -x "$dir/$filename" && perm="$perm executable"
22         echo "The file $dir/$filenam's permission is $perm."
23 done
View Code

評講:此題涉及判斷式與循環的綜合。

【另外一種使用方式——適合於數值運算中】

for ( ( 初始值; 限制值; 執行步長 ) )

do

  程序段

done

解釋:初始值爲某個變量在循環當中的初始值(直接以相似i=1設置好);限制值爲當變量的值在這個限制值的範圍內,就繼續進行循環,例如i<=100;執行步長爲每作一次循環時變量的變化量,如i=i+1。

題目:進行1累加到用戶輸入的循環

 1 #!/bin/bash
 2 # Program:
 3 #       Use for to calculate "1+2+...+${your_input}".
 4 # History:
 5 # 2017-10-1 liuyu release
 6 
 7 read -p "Please input a number, I will count for 1+2+...+your_input: " n
 8 
 9 ans=0
10 for ((i=1; i<=$n; i=i+1))
11 do
12         ans=$(($ans+$i))
13 done
14 echo "The result of '1+2+3+...+$n' is ==> $ans."
sh19.sh

 

11、shell script的追蹤與調試

1. 概述

script在執行以前,最怕出現語法錯誤的問題了!那麼咱們如何調試呢?

咱們有沒有辦法不須要經過直接執行該 script 就能夠來判斷是否有問題呢?

有的,並且很簡單,只要在執行該script的命令中加上相關參數便可。

2. 用法

bash [-nx] 文件名  //-n爲不執行script,僅查詢語法的問題;-x爲將使用到的script內容顯示到屏幕上(執行過程顯示出來,很重要)

相關文章
相關標籤/搜索