第13章 學習shell script

因爲博客園中dollar符號有別的意義,因此文中的dollar符號使用¥表示java

第一個script

[root@localhost script]# cat -n sh01.sh
     1    #!/bin/bash
     2    #Program:
     3    #This program shows "Hello World!" in your screen.
     4    PATH=/usr/local/java/jdk1.8.0_91/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin:~/bin
     5    export PATH;
     6    echo -e "Hello World! \a \n"
     7    exit 0

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

第二三行:註釋shell

第四行:環境變量的聲明,這樣程序執行時能夠直接執行一些外部命令,而沒必要寫絕對路徑bash

第五行:使環境變量生效less

第六行:主程序部分oop

第七行:使用exit命令讓程序中斷,而且傳回一個數值給系統,執行完該script後,使用echo ¥?能夠獲得該值。測試

[root@localhost script]# vi sh01.sh
[root@localhost script]# ./sh01.sh
Hello World!  

//查看上面script返回給系統的值
[root@localhost script]# echo ?
0

 

簡單的shell script練習

交互式腳本:變量內容由用戶肯定

[root@localhost script]# cat -n sh02.sh
     1    #!/bin/bash
     2    PATH=/usr/local/java/jdk1.8.0_91/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin:~/bin
     3    export PATH
     4    
     5    read -p "please input your first name:" firstname #tell user to input their name
     6    read -p "please input your last name:" lastname
     7    echo -e "\n Your full name is:$firstname $lastname"
[root@localhost script]# sh sh02.sh
please input your first name:wu
please input your last name:chao

 Your full name is:wu chao
[root@localhost script]# 

隨日期變化:利用日期建立文件

//查看script腳本
[root@localhost script]# cat sh03.sh
#!/bin/bash
PATH=/usr/local/java/jdk1.8.0_91/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin:~/bin
export PATH

echo -e "I will use 'touch' command to create 3 files."
read -p "please input your file name:" fileuser

filename=¥{fileuser:-"filename"}
date1=¥(date -d -2day +%Y%m%d)
date2=¥(date -d -1day +%Y%m%d)
date3=¥(date +%Y%m%d)

file1=¥{filename}¥{date1}
file2=¥{filename}¥{date2}
file3=¥{filename}¥{date3}

touch "¥file1"
touch "¥file2"
touch "¥file3"

//執行該腳本
[root@localhost script]# sh sh03.sh
I will use 'touch' command to create 3 files.
please input your file name:testFile
[root@localhost script]# 

//查看結果
[root@localhost script]# ls -l testFile*
-rw-r--r--. 1 root root 0 7月  19 12:40 testFile20160717
-rw-r--r--. 1 root root 0 7月  19 12:40 testFile20160718
-rw-r--r--. 1 root root 0 7月  19 12:40 testFile20160719
[root@localhost script]# 

注:¥()是執行裏面的代碼獲得的結果。¥{}取變量的值。ui

數值運算

[root@localhost script]# cat sh04.sh
#!/bin/bash
PATH=/usr/local/java/jdk1.8.0_91/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin:~/bin
export PATH

echo -e "please input two numbers:"
read -p "first number:" n1
read -p "second number:" n2

total=¥((¥n1*¥n2))
echo -e "\n The result of ¥n1 * ¥n2 is ==> ¥total"
[root@localhost script]# 
[root@localhost script]# sh sh04.sh
please input two numbers:
first number:12
second number:23

 The result of 12 * 23 is ==> 276
[root@localhost script]# 

var=¥((運算內容))

用於計算spa

[root@localhost script]# echo ¥((23*3))
69

 

script的執行方式區別(source,sh script,./script)

 利用直接執行的方式執行script

好比使用「sh sh01.sh」來執行腳本時,該腳本會使用一個新的bash環境(子進程)。即腳本實在子進程的bash環境執行的,當執行完後,子進程的變量不會傳給父進程。調試

//查看script腳本中定義了firstname變量
[root@localhost script]# cat sh02.sh
#!/bin/bash
PATH=/usr/local/java/jdk1.8.0_91/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin:~/bin
export PATH

read -p "please input your first name:" firstname #tell user to input their name
read -p "please input your last name:" lastname
echo -e "\n Your full name is:$firstname $lastname"

//直接執行該腳本
[root@localhost script]# sh sh02.sh
please input your first name:wu
please input your last name:chao

 Your full name is:wu chao

//執行完上面的腳本後,在父進程嘗試獲取該變量,發現獲取不到
[root@localhost script]# echo ¥firstname

[root@localhost script]# 

 

利用source執行腳本(父進程中執行)

//查看腳本,含有firstname變量
[root@localhost script]# cat sh02.sh
#!/bin/bash
PATH=/usr/local/java/jdk1.8.0_91/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin:~/bin
export PATH

read -p "please input your first name:" firstname #tell user to input their name
read -p "please input your last name:" lastname
echo -e "\n Your full name is:¥firstname ¥lastname"

//source方法執行腳本
[root@localhost script]# source sh02.sh
please input your first name:wu
please input your last name:chao

 Your full name is:wu chao

//父進程能夠查看到該變量
[root@localhost script]# echo ¥firstname
wu
[root@localhost script]# 

 

善用判斷式

利用test命令的測試功能

判斷文件是否存在

[root@localhost script]# test -e file1 && echo "exist" || echo "not exsit"
not exsit
[root@localhost script]# test -e sh01.sh && echo "exist" || echo "not exsit"
exist
[root@localhost script]# 

經常使用的測試標註以下表:

文件類型判斷

test -e filename

測試標誌 表明意義
-e 該文件名是否存在
-f 該文件名是否存在且爲文件
-d 該文件名是否存在且爲目錄
-b 該文件名是否存在且爲block device設備
-c 該文件名是否存在且爲character device設備
-S 該文件名是否存在且爲一個Socket設備
-p 該文件名是否存在且爲一個FIFO設備
-L 該文件名是否存在且爲一個鏈接文件

文件權限檢測

test -r filename

測試標誌 表明意義
-r 檢測該文件名是否存在且有可讀的權限
-w 檢測該文件名是否存在且有可寫的權限
-x 檢測該文件名是否存在且有可執行的權限
-u 檢測該文件名是否存在且有SUID的權限
-g 檢測該文件名是否存在且有SGID的權限
-k 檢測該文件名是否存在且有Sticky bit的權限
-s 檢測該文件名是否存在且爲非空白文件

兩個文件之間的比較

test file1 -nt file2

測試標誌 表明意義
-nt file1是否比file2新
-ot file1是否比file2舊
-ef file1和file2是否爲同一個文件,便是否指向同一個inode

兩個整數直接的斷定

test n1 -eq n2

測試標誌 表明意義
-eq 兩數值相等
-ne 兩數值不相等
-gt n1>n2
-lt n1<n2
-ge n1>=n2
-le n1<=n2

判斷字符串數據

測試標誌 表明意義
test -z string 判斷是否爲空字符串,空爲true
test -n string 判斷字符串是否爲非空,空爲false
test str1=str2 判斷字符串是否相等
test str1!=str2 判斷字符串是否不相等

 多重條件斷定

測試標誌 表明意義
-a 兩個條件同時成立,如test -r file -a -x file表示file同時具備r與x權限
-o 任意一個條件成立
反向狀態,如test ! -x file。當file不具備x權限時返回true

實例:

[root@localhost script]# cat sh05.sh
#!/bin/bash
PATH=/usr/local/java/jdk1.8.0_91/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin:~/bin
export PATH

echo -e "please input a filename,i will check the file's type and permision.\n\n"
read -p "input a filename:" filename
test -z ¥filename && echo "you must input a filename" && exit 0

test ! -e ¥filename && echo "¥filename is not exsit!" && exit 0
test -f ¥filename && filetype="regulare file"
test -d ¥filename && filetype="directory"
test -r ¥filename && perm="readable"
test -w ¥filename && perm="¥perm writable"
test -x ¥filename && perm="¥perm executable"

echo "the filename:¥filename is a ¥filetype"
echo "and the permissions are: ¥perm"
[root@localhost script]# sh sh05.sh
please input a filename,i will check the file's type and permision.


input a filename:sh02.sh
the filename:sh02.sh is a regulare file
and the permissions are: readable writable
[root@localhost script]# 

利用判斷符號[ ]

[ -z "¥HOME" ] ; echo ¥?

注意中括號兩端都有空格符。

 

當變量比較時,以下:

@localhost script]# s1="hello world"
[root@localhost script]# [ "¥s1" == "hello" ]

而不可使用[ ¥s1 == "hello"]

實例:

[root@localhost script]# cat sh06.sh
#!/bin/bash
PATH=/usr/local/java/jdk1.8.0_91/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin:~/bin
export PATH

echo -e "please input a filename,i will check the file's type and permision.\n\n"
read -p "please input (Y/N):" yn
[ "¥yn" == "Y" -o "¥yn" == "y" ] && echo "OK,continue" && exit 0
[ "¥yn" == "N" -o "¥yn" == "n" ] && echo "On,interrupt" && exit 0
echo "I do not know your choice " && exit 0
[root@localhost script]# sh sh06.sh
please input a filename,i will check the file's type and permision.


please input (Y/N):y
OK,continue
[root@localhost script]# 

shell script的默認變量(¥0,¥1...)

腳本執行時,後面能夠跟多個參數,以下:

sh scriptname.sh opt1 opt2 ...

則¥0表示執行的文件名,¥1表示第一個參數……

 

¥#:表明參數個數

¥@:表明"¥1","¥2","¥3","¥4"之意,每一個變量獨立

¥*:表明"¥1c¥2c¥3c¥4",c爲分隔符,默認爲空格

[root@localhost script]# cat sh07.sh
#!/bin/bash
PATH=/usr/local/java/jdk1.8.0_91/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin:~/bin
export PATH

echo -e "The script name is ==> ¥0"
echo -e "Total parameter number is ==> ¥#"

[ "¥#" -lt 2 ] && echo "The number of parameter is less than 2.Stop here." && exit 0
echo "Your whole parameter is ==> '¥@'"
echo "The 1st parameter is ==> ¥1"


[root@localhost script]# sh sh07.sh one two three four
The script name is ==> sh07.sh
Total parameter number is ==> 4
Your whole parameter is ==> 'one two three four'
The 1st parameter is ==> one
[root@localhost script]# 

 條件判斷式

利用if……then

if [ 條件判斷式1 ]; then

  執行操做

elif [ 條件判斷式2 ]; then

  執行操做

else

  執行操做

fi

利用case...esac判斷

當一個變量存在多個既定變量內容時,可使用該語句針對不一樣的語句內容執行相應的操做。

case ¥變量名 in
    「第一個變量內容」)
     程序段  
    ;;
    「第二個變量內容」)
    程序段
    ;;
    *)  #表示全部其餘值得狀況
    程序段
esac

    舉例:

[root@localhost script]# cat sh08.sh
#!/bin/bash
PATH=/usr/local/java/jdk1.8.0_91/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin:~/bin
export PATH

case1 in
    "hello")
    echo "hello,how are you?"
    ;;
    "")
    echo "you must input parameters, ex>{¥0 someword}"
    ;;
    *)
    echo "Usage ¥0 {hello}"
    ;;
esac

[root@localhost script]# sh sh08.sh wuchao
Usage sh08.sh {hello}
[root@localhost script]# sh sh08.sh hello
hello,how are you?
[root@localhost script]# 

利用function功能

function的設置必定要在程序的前面

[root@localhost script]# cat sh08.sh
#!/bin/bash
PATH=/usr/local/java/jdk1.8.0_91/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin:~/bin
export PATH

function printit(){
    echo -n "Your choice is "
}

case1 in
    "one")
        printit;echo ¥1 | tr 'a-z' 'A-Z'
    ;;
    "two")
        printit;echo ¥1 | tr 'a-z' 'A-Z'
    ;;
    *)
    echo "Usage ¥0 {one|two|three}"
    ;;
esac

[root@localhost script]# sh sh08.sh one
Your choice is ONE
[root@localhost script]# 

 

循環(loop)

while do done, until do done

while [ condition ]

do

  程序段落

done

until [ condition ]

do

  程序段落

done

 

for...do...done

for var in con1 con2 con3...
do
    程序段落
done

示例1:循環遍歷多個字符串

[root@localhost script]# cat sh08.sh
#!/bin/bash
PATH=/usr/local/java/jdk1.8.0_91/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin:~/bin
export PATH

function printit(){
    echo -n "Your choice is "
}

for animal in dog cat tiger
do
    printit;echo "¥{animal}"
done

[root@localhost script]# sh sh08.sh
Your choice is dog
Your choice is cat
Your choice is tiger
[root@localhost script]# 

示例2:顯示/etc/passwd的用戶名和id信息

[root@localhost script]# cat sh08.sh
#!/bin/bash
PATH=/usr/local/java/jdk1.8.0_91/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin:~/bin
export PATH

function printit(){
    echo -n "Your choice is "
}
users=¥(cut -d ':' -f1 /etc/passwd)
for username in ¥users
do
    echo -n "id of user is : ";id ¥username    #id指令用於獲取用戶的id信息
    echo -e "username is :¥{username} \n"
done

[root@localhost script]# sh sh08.sh
id of user is : uid=0(root) gid=0(root) 組=0(root)
username is :root 

id of user is : uid=1(bin) gid=1(bin) 組=1(bin)
username is :bin 

id of user is : uid=2(daemon) gid=2(daemon) 組=2(daemon)
username is :daemon 

id of user is : uid=3(adm) gid=4(adm) 組=4(adm)
username is :adm 

id of user is : uid=4(lp) gid=7(lp) 組=7(lp)
username is :lp 

id of user is : uid=5(sync) gid=0(root) 組=0(root)
username is :sync 

示例3:遍歷數值序列

[root@localhost script]# cat sh09.sh
#!/bin/bash
PATH=/usr/local/java/jdk1.8.0_91/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin:~/bin
export PATH

function printit(){
    echo -n "Your choice is "
}

network="192.168.247.129"
for sitenu in ¥(seq 1 100)
do
    ping -c 1 -w 1 ¥{network}.¥{sitenu} &> /dev/null && result=0 || result=1

    if [ "¥result"==0 ];then
        echo "Server ¥{network}.¥{sitenu} is UP."
    else
        echo "Server ¥{network}.¥{sitenu} is DOWN."
    fi
done

[root@localhost script]# sh sh09.sh
Server 192.168.247.129.1 is UP.
Server 192.168.247.129.2 is UP.
Server 192.168.247.129.3 is UP.
Server 192.168.247.129.4 is UP.
Server 192.168.247.129.5 is UP.
Server 192.168.247.129.6 is UP.
Server 192.168.247.129.7 is UP.
Server 192.168.247.129.8 is UP.
Server 192.168.247.129.9 is UP.

for...do...done的數值處理

for ((初始值;限制值;執行步長))
do
    程序段
done

示例

[root@localhost script]# cat sh10.sh
#!/bin/bash
PATH=/usr/local/java/jdk1.8.0_91/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin:~/bin
export PATH

function printit(){
    echo -n "Your choice is "
}

read -p "please input a number,I will count for 1+2+2+...+yourinput:" nu

s=0
for ((i=1;i<=¥nu;i=i+1))
do
    s=¥((¥s+¥i))
done

echo "The result of 1+2+3+...+¥nu is ==> ¥s"
[root@localhost script]# sh sh10.sh
please input a number,I will count for 1+2+2+...+yourinput:100
The result of 1+2+3+...+100 is ==> 5050
[root@localhost script]# 

shell script的追蹤與調試

sh [-nvx] script.sh

參數:

-n:不執行script,僅查詢語法問題

-v:在執行script前,先將script的內容輸出到屏幕

-x:將使用到的script輸出到屏幕

相關文章
相關標籤/搜索