天天看點

shell腳本程式設計總結

shell腳本程式設計總結

shell是什麼;

Shell是系統的使用者界面,提供了使用者與核心進行互動操作的一種接口。它接收使用者輸入的指令并把它送入核心去執行。

實際上Shell是一個指令解釋器,它解釋由使用者輸入的指令并且把它們送到核心。不僅如此,Shell有自己的程式設計語言用于對指令的編輯,它允許使用者編寫由shell指令組成的程式。Shell程式設計語言具有普通程式設計語言的很多特點,比如它也有循環結構和分支控制結構等,用這種程式設計語言編寫的Shell程式與其他應用程式具有同樣的效果。

Linux提供了像MicrosoftWindows那樣的可視的指令輸入界面--X Window的圖形使用者界面(GUI)。它提供了很多桌面環境系統,其操作就像Windows一樣,有視窗、圖示和菜單,所有的管理都是通過滑鼠控制。GNOME。

shell的種類

每個Linux系統的使用者可以擁有他自己的使用者界面或Shell,用以滿足他們自己專門的Shell需要。

同Linux本身一樣,Shell也有多種不同的版本。主要有下列版本的Shell: Bourne Shell:是貝爾實驗室開發的。

BASH:是GNU的Bourne Again Shell,是GNU作業系統上預設的shell。

Korn Shell:是對Bourne SHell的發展,在大部分内容上與Bourne Shell相容。

C Shell:是SUN公司Shell的BSD版本。

Z Shell:The last shell you’ll ever need! Z是最後一個字母,也就是終極Shell。它內建了bash、ksh的重要特性,同時又增加了自己獨有的特性.

我們在系統上常用的shell是 bash

既然是程式設計,那麼程式設計所常有的概念,在shell中的展現是怎樣的呢?

事實上程式設計中所用到的變量,函數,數組,字元串,條件判斷, 循環結構在shell中都能展現.

shell腳本文法

 第一行必須頂格寫并指明以下所使用的shell 

 #!/bin/bash

 #!/usr/bin/python 

#!/bin/tcsh

各種shell 如bash,python,tcsh任君選擇使用.

定義變量

shell語言是非類型的解釋型語言,強類型語言程式設計時需要事先聲明變量,并聲明其類型 shell程式設計中給一個變量指派就是定義變量. 

shell的變量是無類型的,是以使用者想讓它當字元時就是字元,想讓它當數字就是數字。 

當然,我們還可以用 declare來指定其資料類型

declare 

    -r 隻讀變量 =>相當于其它語言的常量吧,指派後不能修改

    -a    數組

    -i    整型

    -f    函數 

在linux支援的所有shell中,都可以用指派符号(=)為變量指派. 如: 

abc=7 (不能在等号兩側留下空格 ) 

name=abc 

在變量指派之後,隻需在變量前面加一個$去引用. 

echo $abc

7

echo $name

abc 

聲明隻讀變量方法一

[robert@ca2 CA]$ declare -r nb=100 

[robert@ca2 CA]$ nb=101 

-bash: na: readonly variable    =>當嘗試改變隻讀變量的時候,系統會發出警告,提醒這是隻讀變量 

聲明隻讀變量之方法二 将變量變成常量[隻讀變量] 

[robert@ca2 CA]$ readonly na=100 

[robert@ca2 CA]$ echo $na 

100 

[robert@ca2 CA]$ na=20 

shell腳本之條件判斷

有if語句作為條件選擇分支

文法 if 條件判斷;then

執行語句

elif 條件判斷;then

fi if條件判斷結束符

有case作為條件選擇分支 

switch=6

case $switch in

[0-9])

    echo $switch

    ;;

[a-z])

esac

說到if語句結構,就得提及到條件測試

指令執行作為條件測試依據

   如grep 'root' /etc/passwd  将運作指令成功與否作為判斷條件

if grep 'root' /etc/passwd;then

    echo "root 使用者存在"

else

     echo "root 使用者不存在"

fi

shell腳本之 case選擇分支

  比較運算:

   >, <, >=, <=, ==, !=

條件判斷中,存在各種判斷, 各種測試類型如下

  測試類型:根據比較時的操作數的類型

   整型測試:整數比較

   字元測試:字元串比較

   檔案測試:判斷檔案的存在性及屬性等  

   注意:比較運算通常隻在同一種類型間進行  

   整型測試:

    -gt: 例如 [ $num1 -gt $num2 ]

    -lt:

    -ge:

    -le:

    -eq:

    -ne:  

   字元串測試:

    雙目

     >: [[ "$str1" > "$str2" ]]

     <:

     >=

     <=

     ==

     !=  

    單目:

       -n String: 是否不空,不空則為真,空則為假

       -z String: 是否為空,空則為真,不空則假

bash條件測試之檔案測試:  

       -a file

              True if file exists.

       -b file

              True if file exists and is a block special file.

       -c file

              True if file exists and is a character special file.

       -d file

              True if file exists and is a directory.

       -e file

       -f file

              True if file exists and is a regular file.

       -g file

              True if file exists and is set-group-id.

       -h file

              True if file exists and is a symbolic link.

       -k file

              True if file exists and its ''sticky'' bit is set.

       -p file

              True if file exists and is a named pipe (FIFO).

       -r file

              True if file exists and is readable.

       -s file

              True if file exists and has a size greater than zero.

       -t fd True if file descriptor fd is open and refers to a terminal.

       -u file

              True if file exists and its set-user-id bit is set.

       -w file

              True if file exists and is writable.

       -x file

              True if file exists and is executable.

       -O file

              True if file exists and is owned by the effective user id.

       -G file

              True if file exists and is owned by the effective group id.

       -L file

       -S file

              True if file exists and is a socket.

       -N file

              True if file exists and has been modified since it was last read.

       file1 -nt file2

              True if file1 is newer (according to modification date) than file2, or if file1 exists and file2 does not.

       file1 -ot file2

              True if file1 is older than file2, or if file2 exists and file1 does not.

       file1 -ef file2

              True if file1 and file2 refer to the same device and inode numbers.

       -o optname

              True if shell option optname is enabled. See the list of options under the description of the -o option to the set builtin

              below.  

          -a FILE

          -e FILE: 存在則為真;否則則為假;

          -f FILE: 存在并且為普通檔案,則為真;否則為假;

          -d FILE: 存在并且為目錄檔案,則為真;否則為假;

          -L/-h FILE: 存在并且為符号連結檔案,則為真;否則為假;

          -b: 塊裝置

          -c: 字元裝置

          -S: 套接字檔案

          -p: 命名管道  

          -s FILE: 存在并且為非空檔案則為值,否則為假;  

          -r FILE

          -w FILE

          -x FILE  

          file1 -nt file2: file1的mtime新于file2則為真,否則為假;

          file1 -ot file2:file1的mtime舊于file2則為真,否則為假; 

shell腳本之for in 循環

格式 for 變量 in 集合;do 語句體 ; done 循環結束辨別

詳細案例如下

declare -i sum=0 

for i in {1..9};do

     let sum+=$i         //sum=$[$sum+$i] 中括号相加

done

echo $sum        

let計算

shell腳本之for 循環

#!/bin/bash

for ((i=0;$i<10;i++));do

    echo $i

done  

shell腳本之while 循環

num=0

while true ;do

    let num++

    if [ $num -gt 10 ];then

        break

    fi

echo $num

shell腳本之until 循環 ==>與while循環不同的是,until的條件判斷中,條件不成立,循環會繼續進行

until [ $num -gt 10 ];do

shell 腳本之函數使用

function test {

    echo "$1 do you want test function"

}

test 'robert'

shell腳本之數組

 數組是程式設計中,存儲控制資料非常重要的一個手段和方式,但遺憾的是 linux的shell隻支援一維數組

數組其實也是一種變量,不同的是,這個特殊類型的變量内,還可以存其它的變量.

數組的使用

  數組名+索引

   數組元素  

  索引的表示方式:

   數字索引:a[index]

    a[0], a[1]  

   bash 4.0的關聯數組

    a[hello], a[hi]  

   declare -a    索引數組

                 -A     關聯數組

  支援稀疏格式: 

 數組的指派:

  一次對一個元素指派:

 a[0]=0

 a[1]=1

 a[2]=2 

 a[3]=3 

  直接指派:

   arr=(0 1 2 3)

  按索引進行指派:

   a=([0]=0 [3]=3 [2]=2 [1]=1) 

  使用者輸入:

   read -a arr 使用者輸入的方式生成數組 

 數組的通路:

  用索引通路:

   ARRAY[index]

如 a=([0]=0 [3]=3 [2]=2 [1]=1) 

echo a[0]通路索引為0的數組

0 ==>結果為0

 數組的長度: 

[robert@ca2 ~]$ array=([0]=0 [3]=3 [2]=2 [1]=1) 

[robert@ca2 ~]$ echo ${#array[@]} 

 從數組中挑選某元素:

  ${ARRAY[@]:offset:number}

   切片:

    offset: 偏移的元素個數

    number: 取出的元素的個數

[robert@ca2 ~]$ echo ${array[@]:1:2}  

1 2

  ${ARRAY[@]:offset}:取出偏移量後的所有元素

[robert@ca2 ~]$ echo ${array[@]:1} 

1 2 3

  ${ARRAY[@]}: 取出所有元素

[robert@ca2 ~]$ echo ${array[@]} 

0 1 2 3

  使用@和*的不同

  $@: 每個參數是一個獨立的串

  $*: 所有參數是一個串

數組如果想作為對數傳入給函數使用,怎麼辦呢? 

#!/bin/bash  

function myarr {

#echo $@

#exit 0

    newarr=(echo "$@")    接收時轉化為數組

    echo ${newarr[@]}

myarray=(12 23 34 45)

myarr ${myarray[@]}     ==>注,為函數傳遞數組作為變量,需要注意,要将其轉化為N個參數傳入

在程式設計中,字元串的操作是相當頻繁常用的

字元串

字元串切片: 

${string:offset:length}     從左向右取,依稀量,加長度, 如果隻指定偏移量,則偏移後,取所有字串 

取尾部的指定個數的字元: 

${string: -length}         加個 " - " 号,則是從右向左取 

取子串:基于模式 

${variable#*word}:在variable中存儲字串上,自左而右,查找第一次出現word,删除字元開始至此word處的所有内容;  

[root@localhost ~]# url=www.baidu.com 

[root@localhost ~]# echo $url 

www.baidu.com 

[root@localhost ~]# echo ${url#*.}    從左到右,取第一次出現的.号,并從左開始第一個字元删除到第一次出現的字元,    

baidu.com

[root@localhost ~]# echo ${url##*.} 再加一個# 是貪婪模式,找到從左到右,最後一次出現的 . 并從頭到 . 删除

com

${variable##*word}:在variable中存儲字串上,自左而右,查找最後一次出現word,删除字元開始至此word處的所有内容; 

file='/var/log/messages' 

${file#*/}: 傳回的結果是var/log/messages 

${file##*/}: 傳回messages  

${variable%word*}: 在variable中存儲字串上,自右而左,查找第一次出現word,删除此word處至字串尾部的所有内容; 

${variable%%world*}:在variable中存儲字串上,自右而左,查找最後一次出現word,删除此word處至字串尾部的所有内容; 

${file%*/}: 傳回的結果是/var/log 

${file%%*/}: 傳回結果為空  

phonenumber='010-110-8' 

${phonenumber%%-*} 

${phonenumber##*-}  

url="http://www.magedu.com:80" 

  周遊通路一個字元串(預設是以空格分開的,當字元串是由其他字元分隔時可以參考 2)

str="a --m"

for i in $str

do

    echo $i

array

聲明數組 myarray=(1 2 3 ) 

列印數組 echo ${myarray[@]} 

通路數組的長度   ${#myarray[@]} 

[root@localhost ~]# echo ${#myarray[@]} 

3

#直接輸出的是數組的第一個元素

echo $array

#用下标的方式通路數組元素

echo ${array[1]}

#輸出這個數組

echo ${array[@]}

#輸出數組中下标為3的元素的長度

echo ${#array[3]}

#輸出數組中下标 為1到3的元素

echo ${array[@]:1:3}

#輸出數組中下标大于2的元素

echo ${array[@]:2}

#輸出數組中下标小于2的元素

echo ${array[@]::2}

${string:offset:length}     從左向右取,依稀量,加長度, 如果隻指定偏移量,則偏移後,取所有字串

${string: -length}         加個 " - " 号,則是從右向左取

${variable#*word}:在variable中存儲字串上,自左而右,查找第一次出現word,删除字元開始至此word處的所有内容; 

${file##*/}: 傳回messages 

${file%%*/}: 傳回結果為空 

${phonenumber##*-} 

url="http://www.magedu.com:80"

1.長度

[root@localhost ~]$ test='I love china'

[root@localhost ~]$ echo ${#test}

12

${#變量名}得到字元串長度

2.截取字串

[root@localhost ~]$ test='I love china'

[root@localhost ~]$ echo ${test:5}     

e china

[root@localhost ~]$ echo ${test:5:10} 

${變量名:起始:長度}得到子字元串

3.字元串删除

[root@localhost ~]$ test='//tmp/boot.ini'

[root@localhost ~]$ echo ${test#/}

/tmp/boot.ini

[root@localhost ~]$ echo ${test#*/}

[root@localhost ~]$ echo ${test##*/}

boot.ini

[root@localhost ~]$ echo ${test%/*} 

c:/windows

[root@localhost ~]$ echo ${test%%/*}

${變量名#substring正規表達式}從字元串開頭開始配備substring,删除比對上的表達式。

${變量名%substring正規表達式}從字元串結尾開始配備substring,删除比對上的表達式。

注意:${test##*/},${test%/*} 分别是得到檔案名,或者目錄位址最簡單方法。

4.字元串替換

[chengmo@localhost ~]$ test='/tmp/boot.ini'

[chengmo@localhost ~]$ echo ${test/\//\\}

[chengmo@localhost ~]$ echo ${test//\//\\}