Linux Shell編程

Linux Shell編程http://blog.csdn.net/phiall/article/details/54943469

簡介

Shell 是一個用C語言編寫的程序,它是用戶使用Linux的橋樑。Shell既是一種命令語言,又是一種程序設計語言。Shell 是指一種應用程序,這個應用程序提供了一個界面,用戶通過這個界面訪問操作系統內核的服務。Bourne Again Shell,由於易用和免費,Bash在日常工作中被廣泛使用。同時,Bash也是大多數Linux系統默認的Shell。

詳解

1.shell變量

  • 變量名和等號之間不能有空格;

  • 除了顯式地直接賦值,還可以用語句給變量賦值,如:


    for file in `ls /etc` 

  • 推薦給所有變量加上花括號,這是個好的編程習慣,以免出現引用變量varible時出現$varible123引起混淆的情況;

  • 使用 readonly 命令可以將變量定義爲只讀變量,只讀變量的值不能被改變,如:

    myUrl="http://www.w3cschool.cc"
    readonly myUrl
    • 1
    • 2
  • 使用 unset 命令可以刪除變量,語法爲:unset 變量名

  • 字符串是shell編程中最常用最有用的數據類型,字符串可以用單引號,也可以用雙引號,也可以不用引號。

    – 單引號裏的任何字符都會原樣輸出,單引號字符串中的變量是無效的; 
    – 單引號字串中不能出現單引號(對單引號使用轉義符後也不行);

    – 雙引號裏可以有變量 
    – 雙引號裏可以出現轉義字符

  • 雙引號中可以拼接字符串,如:

    your_name="world"
    greeting="hello, "$your_name" !"
    greeting_1="hello, ${your_name} !"
    echo $greeting $greeting_1 #均輸出hello world !
    • 1
    • 2
    • 3
    • 4
  • 字符串長度獲取:

    string="abcd"
    echo ${#string} #輸出 4
    • 1
    • 2
  • 字符串截取:

    string="runoob is a great site"
    echo ${string:1:4} # 輸出 unoo
    • 1
    • 2
  • 查找字串位置:

    string="runoob is a great company"
    echo `expr index "$string" is`  # 輸出 8
    • 1
    • 2
  • bash支持一維數組(不支持多維數組),並且沒有限定數組的大小,數組元素的下標由0開始編號。獲取數組中的元素要利用下標,下標可以是整數或算術表達式,其值應大於或等於0。

    可以不使用連續的下標,而且下標的範圍沒有限制。

    在Shell中,用括號來表示數組,數組元素用”空格”或換行符號分割開

  • 讀取數組指定下標的元素值:

    ${數組名[下標]}
    • 1
  • 獲取數組所有元素:

    ${array_name[@]}
    • 1
  • 獲取數組的長度:

    
    # 取得數組元素的個數
    
    length=${#array_name[@]}
    
    # 或者
    
    length=${#array_name[*]}
    
    # 取得數組單個元素的長度
    
    lengthn=${#array_name[n]}
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

2.shell參數傳遞

  • 可以在執行 Shell 腳本時,向腳本傳遞參數,腳本內獲取參數的格式爲:$nn 代表一個數字,0代表腳本文件名,1 爲執行腳本的第一個參數,2 爲執行腳本的第二個參數,以此類推…

    如test.sh:

    
    #!/bin/bash
    
    
    echo "Shell 傳遞參數實例!";
    echo "執行的文件名:$0";
    echo "第一個參數爲:$1";
    echo "第二個參數爲:$2";
    echo "第三個參數爲:$3";
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    執行./test.sh 1 world reference,輸出內容爲:

    執行的文件名:./test.sh
    第一個參數爲:1
    第二個參數爲:world
    第三個參數爲:reference
    • 1
    • 2
    • 3
    • 4
  • 幾個用於處理傳遞參數的字符含義:

    $#   傳遞到腳本的參數個數
    $*   以一個單字符串顯示所有向腳本傳遞的參數。
    如"$*"用「"」括起來的情況、以"$1 $2$n"的形式輸出所有參數,整體做爲一個字符串回顯。
    $$  腳本運行的當前進程ID號
    $!   後臺運行的最後一個進程的ID號
    $@   與$*相同,但是使用時加引號,並在引號中返回每個參數。
    如"$@"用「"」括起來的情況、以"$1" "$2""$n" 的形式輸出所有參數,每個參數做爲單獨的字符串回顯。
    $-   顯示Shell使用的當前選項,與set命令功能相同。
    $?   顯示最後命令的退出狀態。0表示沒有錯誤,其他任何值表明有錯誤
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

3.shell運算符

原生bash不支持簡單的數學運算,但是可以通過其他命令來實現,例如 awk 和 expr,expr 最常用。

如:

#!/bin/bash
a=3
b=5
cc=`expr $a + $b`
echo $cc
  • 1
  • 2
  • 3
  • 4
  • 5

注:

表達式和運算符之間要有空格,例如 2+2 是不對的,必須寫成 2 + 2,這與我們熟悉的大多數編程語言不一樣;
完整的表達式要被 ` ` 包含;
  • 1
  • 2
  • 算術運算符:

    + 加法  #如`expr $a + $b` 結果爲 30。
    - 減法  #如`expr $a - $b` 結果爲 -10。
    * 乘法  #如`expr $a \* $b` 結果爲  200,這裏*前需要轉義符號;
    / 除法  #如`expr $b / $a` 結果爲 2% 取餘  #如`expr $b % $a` 結果爲 0。
    = 賦值  #如a=$b 將把變量 b 的值賦給 a。
    ==    相等。#用於比較兩個數字,相同則返回 true。    如[ $a == $b ] 返回 false。
    !=    不相等。#用於比較兩個數字,不相同則返回 true。  如[ $a != $b ] 返回 true
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
  • 比較運算符:

    -eq   檢測兩個數是否相等,相等返回 true。    [ $a -eq $b ] 返回 false-ne   檢測兩個數是否相等,不相等返回 true。   [ $a -ne $b ] 返回 true-gt   檢測左邊的數是否大於右邊的,如果是,則返回 true。 [ $a -gt $b ] 返回 false-lt   檢測左邊的數是否小於右邊的,如果是,則返回 true。 [ $a -lt $b ] 返回 true-ge   檢測左邊的數是否大於等於右邊的,如果是,則返回 true。   [ $a -ge $b ] 返回 false-le   檢測左邊的數是否小於等於右邊的,如果是,則返回 true。   [ $a -le $b ] 返回 true
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
  • 布爾運算符:

    ! 非運算,表達式爲 true 則返回 false,否則返回 true。  [ ! false ] 返回 true。
    -o    或運算,有一個表達式爲 true 則返回 true。  [ $a -lt 20 -o $b -gt 100 ] 返回 true-a    與運算,兩個表達式都爲 true 才返回 true。  [ $a -lt 20 -a $b -gt 100 ] 返回 false
    • 1
    • 2
    • 3
  • 邏輯運算符:

    &&    邏輯的 AND [[ $a -lt 100 && $b -gt 100 ]] 返回 false
    ||    邏輯的 OR  [[ $a -lt 100 || $b -gt 100 ]] 返回 true
    • 1
    • 2
  • 字符串運算符:

    = 檢測兩個字符串是否相等,相等返回 true。  [ $a = $b ] 返回 false!=    檢測兩個字符串是否相等,不相等返回 true。 [ $a != $b ] 返回 true-z    檢測字符串長度是否爲0,爲0返回 true。  [ -z $a ] 返回 false-n    檢測字符串長度是否爲0,不爲0返回 true。 [ -n $a ] 返回 truestr   檢測字符串是否爲空,不爲空返回 true。   [ $a ] 返回 true。
    • 1
    • 2
    • 3
    • 4
    • 5
  • 文件測試運算符:

    -b file   檢測文件是否是塊設備文件,如果是,則返回 true。  [ -b $file ] 返回 false-c file   檢測文件是否是字符設備文件,如果是,則返回 true。 [ -c $file ] 返回 false-d file   檢測文件是否是目錄,如果是,則返回 true。 [ -d $file ] 返回 false-f file   檢測文件是否是普通文件(既不是目錄,也不是設備文件),如果是,則返回 true。    [ -f $file ] 返回 true-g file   檢測文件是否設置了 SGID 位,如果是,則返回 true。  [ -g $file ] 返回 false-k file   檢測文件是否設置了粘着位(Sticky Bit),如果是,則返回 true。  [ -k $file ] 返回 false-p file   檢測文件是否是有名管道,如果是,則返回 true。   [ -p $file ] 返回 false-u file   檢測文件是否設置了 SUID 位,如果是,則返回 true。  [ -u $file ] 返回 false-r file   檢測文件是否可讀,如果是,則返回 true。  [ -r $file ] 返回 true-w file   檢測文件是否可寫,如果是,則返回 true。  [ -w $file ] 返回 true-x file   檢測文件是否可執行,如果是,則返回 true。 [ -x $file ] 返回 true-s file   檢測文件是否爲空(文件大小是否大於0),不爲空返回 true。 [ -s $file ] 返回 true-e file   檢測文件(包括目錄)是否存在,如果是,則返回 true。    [ -e $file ] 返回 true
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

4.shell echo命令

#!/bin/bash
#-e 開啓轉義
#\c 不換行

echo "test\n" #輸出test\n,換行
echo -e "test\n" #輸出test和一個空行
echo -e "test\c" #輸出test,且不換行
echo `date` #顯示執行命令的結果
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

運行結果:

test\n
test

test2017年 02月 08日 星期三 14:31:58 CST
  • 1
  • 2
  • 3
  • 4

5.shell printf命令

printf 命令模仿 C 程序庫(library)裏的 printf() 程序。標準所定義,因此使用printf的腳本比使用echo移植性好。printf 使用引用文本或空格分隔的參數,外面可以在printf中使用格式化字符串,還可以指定字符串的寬度、左右對齊方式等。默認printf不會像 echo 自動添加換行符,我們可以手動添加 \n。

printf 命令的語法:

printf  format-string  [arguments...]
  • 1

如:

printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234
  • 1

注:

%s %c %d %f都是格式替代符
%-10s 指一個寬度爲10個字符(-表示左對齊,沒有則表示右對齊),任何字符都會被顯示在10個字符寬的字符內,如果不足則自動以空格填充,超過也會將內容全部顯示出來
%-4.2f 指格式化爲小數,其中.2指保留2位小數。
  • 1
  • 2
  • 3

6.shell test 命令

Shell中的 test 命令用於檢查某個條件是否成立,它可以進行數值、字符和文件三個方面的測試。

  • 數值測試:

    -eq   等於則爲真
    -ne   不等於則爲真
    -gt   大於則爲真
    -ge   大於等於則爲真
    -lt   小於則爲真
    -le   小於等於則爲真
    
    num1=100
    num2=100
    if test $[num1] -eq $[num2]
    then
      echo '兩個數相等!'
    else
      echo '兩個數不相等!'
    fi
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
  • 字符串測試:

    = 等於則爲真
    !=    不相等則爲真
    -z 字符串    字符串的長度爲零則爲真
    -n 字符串    字符串的長度不爲零則爲真
    
    num1="ru1noob"
    num2="runoob"
    if test $num1 = $num2
    then
      echo '兩個字符串相等!'
    else
      echo '兩個字符串不相等!'
    fi
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
  • 文件測試:

    -e 文件名    如果文件存在則爲真
    -r 文件名    如果文件存在且可讀則爲真
    -w 文件名    如果文件存在且可寫則爲真
    -x 文件名    如果文件存在且可執行則爲真
    -s 文件名    如果文件存在且至少有一個字符則爲真
    -d 文件名    如果文件存在且爲目錄則爲真
    -f 文件名    如果文件存在且爲普通文件則爲真
    -c 文件名    如果文件存在且爲字符型特殊文件則爲真
    -b 文件名    如果文件存在且爲塊特殊文件則爲真
    
    cd /bin
    if test -e ./bash
    then
      echo '文件已存在!'
    else
      echo '文件不存在!'
    fi
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
  • Shell還提供了與( -a )、或( -o )、非( ! )三個邏輯操作符用於將測試條件連接起來,其優先級爲:”!”最高,”-a”次之,”-o”最低。

    如:

    cd /bin
    if test -e ./notFile -o -e ./bash
    then
      echo '有一個文件存在!'
    else
      echo '兩個文件都不存在'
    fi
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

7.Shell 條件控制

sh的流程控制不可爲空,在sh/bash裏如果else分支沒有語句執行,就不要寫這個else。

  • if語法結構:

    if condition
    then
      command1 
      command2
      ...
      commandN 
    fi
    
    例如:
    if [ $(ps -ef | grep -c "ssh") -gt 1 ]; then echo "true"; fi
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
  • if else語法結構:

    if condition
    then
      command1 
      command2
      ...
      commandN
    else
      command
    fi
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
  • if else-if else語法結構:

    if condition1
    then
      command1
    elif condition2 
    then 
      command2
    else
      commandN
    fi
    
    例如:
    a=10
    b=20
    if [ $a == $b ]
    then
     echo "a 等於 b"
    elif [ $a -gt $b ]
    then
     echo "a 大於 b"
    elif [ $a -lt $b ]
    then
     echo "a 小於 b"
    else
     echo "沒有符合的條件"
    fi
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
  • for 循環

    for var in item1 item2 ... itemN
    do
      command1
      command2
      ...
      commandN
    done
    
    例如:
    for loop in 1 2 3 4 5
    do
      echo "The value is: $loop"
    done
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
  • while 語句

    while condition
    do
      command
    done
    
    例如:
    
    #!/bin/sh
    
    int=1
    while(( $int<=5 ))
    do
          echo $int
          let "int++"
    done
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
  • 無限循環

    while :
    do
      command
    done
    或
    while true
    do
      command
    done
    或
    for (( ; ; ))
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
  • until 循環

    until condition
    do
      command
    done
    • 1
    • 2
    • 3
    • 4
  • case

    case 值 in
    模式1)
      command1
      command2
      ...
      commandN
      ;;
    模式2)
      command1
      command2
      ...
      commandN
      ;;
    esac
    
    例如:
    echo '輸入 1 到 4 之間的數字:'
    echo '你輸入的數字爲:'
    read aNum
    case $aNum in
      1)  echo '你選擇了 1'
      ;;
      2)  echo '你選擇了 2'
      ;;
      3)  echo '你選擇了 3'
      ;;
      4)  echo '你選擇了 4'
      ;;
      *)  echo '你沒有輸入 1 到 4 之間的數字'
      ;;
    esac
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

8.shell 函數

inux shell 可以用戶定義函數,然後在shell腳本中可以隨便調用。shell中函數的定義格式如下:

[ function ] funname [()]
{
    action;
    [return int;]
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 可以帶function fun() 定義,也可以直接fun() 定義,不帶任何參數。
  • 參數返回,可以顯示加:return 返回,如果不加,將以最後一條命令運行結果,作爲返回值。 return後跟數值n(0-255)

無參 無顯示返回值函數

demoFun(){
    echo "這是我的第一個 shell 函數!"
}
  • 1
  • 2
  • 3

帶顯示返回值函數

funWithReturn(){
    echo "這個函數會對輸入的兩個數字進行相加運算..."
    echo "輸入第一個數字: "
    read aNum
    echo "輸入第二個數字: "
    read anotherNum
    echo "兩個數字分別爲 $aNum$anotherNum !"
    return $(($aNum+$anotherNum))
}
funWithReturn
echo "輸入的兩個數字之和爲 $? !" ##返回命令執行狀態
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

帶參函數

funWithParam(){
    echo "第一個參數爲 $1 !"
    echo "第二個參數爲 $2 !"
    echo "第十個參數爲 $10 !"
    echo "第十個參數爲 ${10} !"
    echo "第十一個參數爲 ${11} !"
    echo "參數總數有 $# 個!"
    echo "作爲一個字符串輸出所有參數 $* !"
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

處理參數的幾個特殊字符

$# 傳遞到腳本的參數個數
$* 以一個單字符串顯示所有向腳本傳遞的參數
$$    腳本運行的當前進程ID$! 後臺運行的最後一個進程的ID$@$*相同,但是使用時加引號,並在引號中返回每個參數。
$- 顯示Shell使用的當前選項,與set命令功能相同。
$? 顯示最後命令的退出狀態。0表示沒有錯誤,其他任何值表明有錯誤。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

8.Shell 輸入/輸出重定向

重定向命令列表

command > file  將輸出重定向到 file
command < file  將輸入重定向到 file
command >> file 將輸出以追加的方式重定向到 file
n > file    將文件描述符爲 n 的文件重定向到 file。
n >> file   將文件描述符爲 n 的文件以追加的方式重定向到 file。
n >& m  將輸出文件 m 和 n 合併。
n <& m  將輸入文件 m 和 n 合併。
<< tag  將開始標記 tag 和結束標記 tag 之間的內容作爲輸入。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 一般情況下,每個 Unix/Linux 命令運行時都會打開三個文件: 
    標準輸入文件(stdin):stdin的文件描述符爲0,Unix程序默認從stdin讀取數據。 
    標準輸出文件(stdout):stdout 的文件描述符爲1,Unix程序默認向stdout輸出數據。 
    標準錯誤文件(stderr):stderr的文件描述符爲2,Unix程序會向stderr流中寫入錯誤信息。

  • Here Document 是 Shell 中的一種特殊的重定向方式,用來將輸入重定向到一個交互式 Shell 腳本或程序。它的基本的形式如下:

    command << delimiter
      document
    delimiter
    • 1
    • 2
    • 3

    它的作用是將兩個 delimiter 之間的內容(document) 作爲輸入傳遞給 command。

    注:

    結尾的delimiter 一定要頂格寫,前面不能有任何字符,後面也不能有任何字符,包括空格和 tab 縮進。
    開始的delimiter前後的空格會被忽略掉。
    • 1
    • 2

9.Shell 文件包含

和其他語言一樣,Shell 也可以包含外部腳本。這樣可以很方便的封裝一些公用的代碼作爲一個獨立的文件。Shell 文件包含的語法格式如下:

. filename   # 注意點號(.)和文件名中間有一空格source filename
  • 1
  • 2
  • 3
  • 4
  • 5

參考

http://www.runoob.com/linux/linux-shell.html


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