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

shell腳本之條件判斷

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

語法 if 條件判斷;then

執行語句

elif 條件判斷;then

執行語句

fi if條件判斷結束符

有case作爲條件選擇分支 

 #!/bin/bash

switch=6

case $switch in

[0-9])

    echo $switch

    ;;

[a-z])

    echo $switch

    ;;

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

              True if file exists.

       -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

              True if file exists and is a symbolic link.

       -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

done

echo $num

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

num=0

until [ $num -gt 10 ];do

    let num++

done

echo $num

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 ~]$ array=([0]=0 [3]=3 [2]=2 [1]=1) 

[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/messages' 
${file%*/}: 返回的結果是/var/log 
${file%%*/}: 返回結果爲空  
phonenumber='010-110-8' 
${phonenumber%%-*} 
${phonenumber##*-}  
url="http://www.magedu.com:80" 

  遍歷訪問一個字符串(默認是以空格分開的,當字符串是由其他字符分隔時可以參考 2)
#!/bin/bash
str="a --m"
for i in $str
do
    echo $i
done


array

聲明數組 myarray=(1 2 3 ) 
打印數組 echo ${myarray[@]} 
1 2 3

訪問數組的長度   ${#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處的所有內容; 

[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/messages' 
${file%*/}: 返回的結果是/var/log 
${file%%*/}: 返回結果爲空 

phonenumber='010-110-8' 
${phonenumber%%-*} 
${phonenumber##*-} 

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

  遍歷訪問一個字符串(默認是以空格分開的,當字符串是由其他字符分隔時可以參考 2)
#!/bin/bash
str="a --m"
for i in $str
do
    echo $i
done

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} 
e china

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

 

3.字符串刪除

[root@localhost ~]$ test='//tmp/boot.ini'
[root@localhost ~]$ echo ${test#/}
/tmp/boot.ini
[root@localhost ~]$ echo ${test#*/}
/tmp/boot.ini
[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/\//\\}
/tmp/boot.ini

[chengmo@localhost ~]$ echo ${test//\//\\}
/tmp/boot.ini


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章