Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.

Bash shell script 教學

10.092 Aufrufe

Veröffentlicht am

Bash shell script 教學

Veröffentlicht in: Software
  • Sex in your area is here: ❤❤❤ http://bit.ly/39pMlLF ❤❤❤
       Antworten 
    Sind Sie sicher, dass Sie …  Ja  Nein
    Ihre Nachricht erscheint hier
  • Follow the link, new dating source: ❶❶❶ http://bit.ly/39pMlLF ❶❶❶
       Antworten 
    Sind Sie sicher, dass Sie …  Ja  Nein
    Ihre Nachricht erscheint hier

Bash shell script 教學

  1. 1. BASH SHELL SCRIPT 教學 1
  2. 2. 建立第一個 HELLO WORLD 腳本 (SCRIPT) #!/bin/bash echo "hello world" 儲存成 hello.sh 2
  3. 3. 執行腳本 $chmod +x hello.sh $./hello.sh 或者 $bash hello.sh 3
  4. 4. 指令與參數 (COMMAND AND ARGUMENT) bash 會依照空格本分辨指令及參數 指令 參數1 參數2 … 參數n $touch a b c $touch a b c # 即使超過一個空格也沒問題 4
  5. 5. 指令與參數 5 $echo "Today Very Big" Today Very Big $echo Today Very Big Today Very Big $echo Today Very Big Today Very Big echo 後面接了三個參數 echo 後面只接了一個參數 (字串) 因此,會輸出含空白的 Today Very Big
  6. 6. 參數的設定 $var=abc O $var = abc X $var =abc X 6 變數與 = 之間不能有空白,有空白會被當成指令的參數
  7. 7. 參數的使用 7 $touch "you are my friend.mp3" $file="you are my friend.mp3" $rm $file rm: cannot remove `you': No such file or directory rm: cannot remove `are': No such file or directory rm: cannot remove `my': No such file or directory rm: cannot remove `friend.mp3': No such file or directory rm $file 展開會,會變成 rm you are my friend.mp3 (共四個參數,但我們需要把它變成一個) $rm "$file" 修正:把 $file 加上雙引號就可以了
  8. 8. 變數 (VARIABLE) 8 類型 指令 說明 陣列 declare -a variable 字串陣列 組合陣列 declare -A variable 可用字串當索引的陣列 整數 declare -i variable 整數變數 只能讀取 declare -r variable=value 只能讀取的變數,無法修改 匯出 declare -x variable 可以匯出到子程序的變數
  9. 9. 參數擴展 (PARAMETER EXPANSION) 9 $echo "$USER, $USERs, ${USER}s" coming, , comings 使用參數擴展時,可以利用大括號限設參數名稱
  10. 10. 特別變數 10 變數 使用方式 說明 0 $0 執行的腳本名稱 1..N $1 執行腳本時,所輸入的第 1 (N) 個參數 # $# 參數的個數 * $* 把所有的參數整理成一個字串 @ $@ 把所有的參數整理成一個陣列 ? $? 上一個前景指令的執行反回值 $ $$ 目前 shell 的程序識別碼 ! $! 上一次執行的背景指令程序識別碼 _ $_ 上一次執行的指令所帶的最後一個參數
  11. 11. 特別變數範例 11 echo "$0 = $0" echo "$1 = $1" echo "$2 = $2" echo "$# = $#" echo "$* = $*" echo "$@ = $@" echo "$? = $?" echo "$$ = $$" echo "$! = $!" echo "$_ = $_"
  12. 12. 特別變數範例 12 $ if.sh para1 para2 $0 = /media/sf_share/if.sh $1 = para1 $2 = para2 $# = 2 $* = para1 para2 $@ = para1 para2 $? = 0 $$ = 2076 $! = $_ = $! = 執行結果
  13. 13. 數術運算 13 i=5 ((i=i*4)) ((i=i/2)) ((i=i+2)) ((i=i-2)) ((i--)) ((i++)) 使用 ((...)) 進行數學運算
  14. 14. 使用指令執行結果當參數 14 now=`date` echo "now = $now" now=$(date) echo "now = $now" 可以使用 `COMMAND` 或是 $(COMMAND) ` 是在鍵盤 1 左邊的符號 now = Sun Nov 2 10:26:56 CST 2014 now = Sun Nov 2 10:26:56 CST 2014 執行結果
  15. 15. TEST 指令 15 test Expression [ Expression ] 0: True 1: False $[ 1 = 2 ]; echo $? # $? 為前一個指令的回傳值 1 $[ 1 = 1 ]; echo $? 0 範例 語法
  16. 16. TEST 指令字串判斷 16 $myname='Michael Jackson' yourname='Michael Jordan' $[ $myname = $yourname ] -bash: [: too many arguments $myname='Michael Jackson' yourname='Michael Jordan' $[ Michael Jackson = Michael Jordon ] -bash: [: too many arguments 實際的執行狀況,參數被展開了,但沒用雙引號括起來 $myname='Michael Jackson' yourname='Michael Jordan' $[ "$myname" = "$yourname" ] $[[ $myname = $yourname ]] 修正:加上雙引號,或是改使用 [[ 與 ]]
  17. 17. TEST 指令檔案判斷 17 指令 說明 -e FILE 判斷 FILE 是否存在 -f FILE 判斷 FILE是否存在且為檔案(file)? -d FILE 判斷 FILE是否存在且為目錄(directory)? -h FILE 判斷 FILE是為符號式連結 -p FILE 判斷 FILE是否存在且為一個 FIFO (pipe) 檔案? -r FILE 判斷 FILE是否存在且具有『可讀』的權限? -s FILE 判斷 FILE是否存在且為『非空白檔案』? -w FILE 判斷 FILE是否存在且具有『可寫』的權限? -x FILE 判斷 FILE是否存在且具有『可執行』的權限?
  18. 18. TEST 指令檔案判斷 18 指令 說明 -O FILE 判斷 FILE的擁有者是否為執行腳本的使用者 -G FILE 判斷 FILE的擁有者是否為執行腳本的使用者的所屬群組 FILE1 -nt FILE2 判斷 FILE1 是否比 FILE2 還新 FILE1 -ot FILE2 判斷 FILE1 是否比 FILE2 還舊
  19. 19. TEST 指令字串判斷 19 指令 說明 -z STR 判斷 STR 的長度是否為 0 -n STR 判斷 STR 的長度是否不為 0 STR1 = STR2 判斷 STR1 是否與 STR2 相同 STR1 != STR2 判斷 STR1 是否與 STR2 不相同 STR1 < STR2 判斷 STR1 在排序時,是否排在 STR2 後面 STR1 > STR2 判斷 STR1 在排序時,是否排在 STR2 前面
  20. 20. TEST 指令整數判斷 20 指令 說明 INT1 -eq INT2 INT1 是否等於 INT2 (=) INT1 -ne INT2 INT1 是否不等於 INT2 (!=) INT1 -lt INT2 INT1 是否小於 INT2 (<) INT1 -gt INT2 INT1 是否大於 INT2 (>) INT1 -le INT2 INT1 是否小於或等於 INT2 (<=) INT1 -ge INT2 INT1 是否大於或等於 INT2 (>=) 注意, >, <, = 是給字串用的
  21. 21. TEST 指令其它判斷 21 指令 說明 EXPR1 -a EXPR2 當 EXPR1 與 EXPR2 皆為 True 時,則為 True EXPR1 -o EXPR2 當 EXPR1 或 EXPR2 為 True 時,則為 True !EXPR NOT 運算,當 EXPR 為 False 時則為 True
  22. 22. [[ 額外的判斷 22 指令 說明 STR = (或 ==) PATTERN 比對 STR 是否符合 glob pattern STR =~ REGEX 比對 STR 是否符合 REGEX EXPR1 && EXPR2 與 [ -a 相同,但是當 EXPR1 為 True 時, 才會推算 EXPR2 EXPR1 || EXPR2 與 [ -o 相同,但是當 EXPR1 為 True 時, 才不會推算 EXPR2 (EXPR) 改變推算的順序
  23. 23. GLOB 樣版 (GLOB PATTERN) 23 樣版 說明 * 符合任何字串,包含空字串 ? 符合任何單一字元 [...] 符合任何在括號內的字元 $ echo * # 顯示在目前目錄下,所有的目錄及檔案(如果有的話) $ touch a.txt b.txt c.txt aa.txt $ echo ?.txt # 顯示在目前目錄下,只包含一個字元的 txt 檔 a.txt b.txt c.txt $ echo [ab].txt # 顯示在目前目錄下,以a或b為檔名的 txt 檔 a.txt b.txt $ echo [ab]?.txt # 顯示在目前目錄下,以a或b為開頭,二個字元為檔名 a.txt b.txt # 的 txt 檔
  24. 24. IF 條件式判斷 24 if COMMANDS # 透過 COMMAND 的執行結果來判斷 TRUE/FALSE, $? then OTHER COMMANDS fi if COMMANDS then OTHER COMMANDS fi if COMMANDS; then OTHER COMMANDS fi if [ 1 –gt 2] # 實際上,就是執行 test 指令,所以要注意空格 then echo "True" fi 語法 範例
  25. 25. IF ELSE 條件式判斷 25 if COMMANDS then OTHER COMMANDS else OTHER COMMANDS fi if [ a = b ] # 實際上,就是執行 test 指令,所以要注意空格 then echo "True" else echo "False" fi 語法 範例
  26. 26. IF ELIF ELSE 條件式判斷 26 if COMMANDS; then OTHER COMMANDS elif COMMAND; then OTHER COMMANDS else OTHER COMMANDS fi if [ 1 = 2 ]; then echo "1 == 2" elif [ 1 = 3 ]; then echo "1 == 3" else echo "1 != 2 and 1 != 3" fi 範例 語法
  27. 27. IF 範例 27 # 判斷 a.txt 是否存在 if [ -e a.txt ]; then echo "a.txt exists" else echo "a.txt doesn't exist" fi # 判斷 tmp 是否為目錄 if [ -d tmp ]; then echo "tmp is a directory" else echo "tmp isn't a directory " fi a.txt exists tmp isn't a directory 輸出
  28. 28. IF 範例-使用 AND 運算 28 if [ 1 = 1 ] && [ 2 = 2 ]; then echo "true" else echo "false" fi if [ 1 = 1 -a 2 = 2 ]; then echo "true" else echo "false" fi
  29. 29. IF 範例-使用 OR 運算 29 if [ 1 = 1 ] || [ 2 = 2 ]; then echo "true" else echo "false" fi if [ 1 = 1 -o 2 = 2 ]; then echo "true" else echo "false" fi
  30. 30. IF 範例-使用 NOT 運算 30 if [ ! 1 = 1 ]; then # 在 [ 後加上 ! 就行了 echo "true" else echo "false" fi
  31. 31. IF 範例-實作加減法 31 if [ ! $# -eq 3 ]; then echo "${0} param1 [+|-] param2" echo "e.g. " echo "${0} param1 + param2" echo "${0} param1 - param2" exit fi if [ $2 == '+' ]; then echo "result = $(($1+$3))" elif [ $2 = '-' ]; then echo "result = $(($1-$3))" else echo "unknown operation: $2" fi $add.sh 1 - 6 result = -5 $add.sh 1 + 6 result = 7 輸出
  32. 32. IF 範例-巢狀結構 32 if [ $1 -gt 20 ]; then if [ $1 -gt 25 ]; then echo "$1 > 25" else echo "20 < $1 <= 25" fi elif [ $1 -gt 10 ]; then if [ $1 -gt 15 ]; then echo "15 < $1 <= 20" else echo "10 < $1 <= 15" fi else echo "$1 <= 10" fi $./exam.sh 6 6 <= 10 $./exam.sh 11 10 < 11 <= 15 $./exam.sh 16 15 < 16 <= 20 $./exam.sh 21 20 < 21 <= 25 $./exam.sh 26 26 > 25 輸出
  33. 33. WHILE 迴圈 33 while COMMAND; do OTHER COMMANDs done while COMMAND do OTHER COMMANDs done while COMMAND do OTHER COMMANDs done
  34. 34. WHILE 迴圈範例 34 while ! ping -c 1 -W 1 1.2.3.4 do echo "still waiting for 1.2.3.4" sleep 1 done while true do echo "Infinite loop" done 無窮回圈 不斷地 ping 1.2.3.4 直到成功為止
  35. 35. WHILE 迴圈範例 35 (( i=10 )); # 透過 (( )) 進行算術運算 while (( i > 0 )) do echo "i = $i" (( i-- )) done 從 i = 10..1, 輸出 i = 10 到 i = 1
  36. 36. WHILE 迴圈範例 36 i=1 result=0 while((i<50)) do ((result=result+i)) ((i=i+1)) done echo $result 計算 1+2+3...+50 的結果
  37. 37. WHILE 範例-讀取檔案 37 N=0 # 行號變數 while read line # 透過 read 指令,從標準輸入讀入一行到變數 line do ((N=N+1)) # 行號累加 echo "$N: $line" done < $1 # 把 $1 檔案導到 while 指令的標準輸入 使用 read 指令及標準輸入的重新導向讀取檔案
  38. 38. 範例資料檔 38 Jim Lin,4,41 Tim Lee,8,12 Johnson Lin,6,20 Tom Wang,1,31 Esko Huang,2,51 Jaska Lu,5,19 Erkk Zhuang,7,9
  39. 39. WHILE 範例-讀取檔案資料 39 while read line # 透過 read 指令,從標準輸入讀入一行到變數 line do IFS=',' # 設定分隔符號為 , read -a record <<< "$line" # 以 , 為分隔符號, # 把 $line 的字串讀入陣列 record echo ${record[0]} echo ${record[1]} echo ${record[2]} done < $1 # 把 $1 檔案導到 while 指令的標準輸入
  40. 40. FOR 迴圈 40 for variable in {n..N}; do COMMANDs done for i in {10..1}; do echo $i done for i in {1..10}; do echo $i done 語法1 整數變數 範例
  41. 41. FOR 迴圈 41 for variable in str1 str2 ... strn; do COMMANDs done for i in a b c; do echo $i done str="a b c" for i in $str; do echo $i done 語法2 字串陣列 範例 a b c 輸出
  42. 42. FOR 迴圈 42 str="a b c" for i in "$str"; do # 輸入的參數變成 "a b c" 而不是 a b c echo $i done a b c 輸出 字串陣列加上雙引號會變回單一字串
  43. 43. FOR 迴圈-腳本參數處理 43 for i in $* do echo $i done $@ 不加雙引號 for i in "$*" do echo $i done $@ 加雙引號 $./exam.sh a a b a a b $./exam.sh a a b a a b 輸出 輸出
  44. 44. FOR 迴圈-腳本參數處理 44 for i in $@ do echo $i done $@ 不加雙引號 for i in "$@" do echo $i done $@ 加雙引號 $./exam.sh a a b a a b $./exam.sh a a b a a b 輸出 輸出
  45. 45. FOR 迴圈 45 for i in *; do # 使用 glob pattern * echo $i done course Desktop Documents Downloads examples.desktop Music Pictures Public Templates tmp Videos 輸出 利用 for loop 及 Glob Pattern 輸出目前目錄下所有的檔案及目錄
  46. 46. FOR 迴圈 46 for i in *.txt; do # 使用 glob pattern * echo $i done $touch a.txt b.txt a.sh b.sh $./exam.sh a.txt b.txt 輸出 輸出以 txt 為副檔名的檔案
  47. 47. FOR 迴圈-讀檔 47 for line in $(cat $1) do echo "$line" done $./exam.sh exam.sh #!/bin/bash for line in $(cat $1) do echo "$line" done 輸出: 不是以行為單位輸出
  48. 48. FOR 迴圈-讀檔(修正) 48 IFS=$'n' # 設定分隔符號為 n for line in $(cat $1) do echo "$line" done $./exam.sh exam.sh #!/bin/bash IFS=$'n' for line in $(cat $1) do echo "$line" done 輸出: 以行為單位輸出
  49. 49. BREAK 與 CONTINUE  break  中斷目前迴圈執行  continue  中止目前的執行,改執行迴圈的下一次執行 49
  50. 50. BREAK 與 CONTINUE 50 for i in {1..5} do if [ $i == 2 ]; then continue; # 碰到 2 則直接執行迴圈的下一次執行 elif [ $i == 4 ]; then break; # 碰到 4 執直接離開迴圈 fi echo $i done $./exam.sh 1 3 輸出: 2 被跳過,迴圈執行 4 就中止,沒有執行到 5
  51. 51. SWITCH 51 case expression in pattern1 ) statements ;; pattern2 ) statements ;; ... esac
  52. 52. SWITCH 範例 52 case expression in pattern1 ) statements ;; pattern2 ) statements ;; ... esac
  53. 53. SWITCH 範例 字串的比較 53 case "$1" in george) echo "Hello George!";; mary) echo "Good morning Mary";; *) echo "Who are you, $1?";; esac $./exam.sh mary Good morning Mary $./exam.sh george Hello George! $./exam.sh jonh Who are you, jonh? 輸出
  54. 54. SWITCH 範例 數字的比較 54 case "$1" in 1) echo "This is No.1";; 2) echo "This is No.2";; *) echo ""Unkonwn number $1";; esac $./exam.sh 1 This is No.1 $./exam.sh 2 This is No.2 $./exam.sh 3 Unkonwn number 3 輸出
  55. 55. SELECT 選擇迴圈 55 select variable in str1 str2 ... strn; do COMMANDs done
  56. 56. SELECT 選擇迴圈範例-選擇檔案 56 select filename in *; do echo "you pick $filename $REPLY " break # 要透過 break 中止 select 迴圈的執行,不然會一直詢問 done $./exam.sh 1) a.sh 3) b.sh 5) exam.sh 7) score.txt 2) a.txt 4) b.txt 6) if.sh #? 3 you pick b.sh 3 輸出
  57. 57. SELECT 選擇迴圈範例-選擇顏色 57 select color in red green blue; do case $color in "$quit") echo "bye" break # 透過 break 指令離開 selec 迴圈 ;; *) echo "you pick $color color $REPLY" ;; esac done 選擇 red/green/blue 三種顏色,或是輸入 quit 離開
  58. 58. SELECT 選擇迴圈範例-選擇顏色 58 輸出 $./exam.sh 1) red 2) green 3) blue #? 1 you pick red color 1 #? 2 you pick green color 2 #? 3 you pick blue color 3 #? quit bye
  59. 59. 函式 (FUNCTION) 59 function FunctionName { COMMANDS } FunctionName () { COMMANDS } 語法1: 使用 function 關鍵字宣告 語法2: 不使用 function 關鍵字宣告,但需加入 ()
  60. 60. 函式 (FUNCTION) 60 hello () { echo -e "hello, $1 = $1, $2 = $2n" } hello 1 2 # 執行函式 $./exam.sh hello, $1 = 1, $2 = 2 輸出
  61. 61. 函式回傳值 61 is_equal_to () { if [ $1 -eq $2 ]; then return 0 fi return 1 } is_equal_to 1 2 echo $? is_equal_to 1 1 echo $? $./exam.sh 1 0 輸出
  62. 62. 離開執行 (EXIT) 62 exit_func () { if [ $1 = 1 ]; then echo "exit in func" exit 1 fi } exit_func $1 echo "exit in main" exit 0 $./exam.sh 0; echo $? exit in main 0 $./exam.sh 1; echo $? exit in func 輸出
  63. 63. 全域及區域變數 63 global_var="global value" # 宣告 local_var 變數 echo "$local_var = $local_var" # 尚未有 local_var 變數 func1 () { local_var="func1" global_var="func1" echo "$local_var = $local_var" echo "$global_var = $global_var" } func2 () { local_var="func2" global_var="func2" echo "$local_var = $local_var" echo "$global_var = $global_var" } echo "execute func1" func1 echo "execute func2" func2 echo "back to main" echo "$local_var = $local_var" echo "$global_var = $global_var"
  64. 64. 全域及區域變數 64 $./exam.sh $local_var = # local_var 尚未被宣告,所以無值 execute func1 $local_var = func1 $global_var = func1 # global_var 已宣告過 execute func2 $local_var = func2 # local_var 已在 func 1 被宣告 $global_var = func2 back to main $local_var = func2 # 皆為 func2 修改過後的結果 $global_var = func2 輸出
  65. 65. 全域及區域變數-使用 LOCAL 65 VAR="global" func() { echo $VAR local VAR="local" echo $VAR } func echo $VAR 使用 local 宣告變數後,該變數便只能在函式內使用 $./exam.sh global # 在 func 內讀取的 VAR 值為 global local # 使用 local 宣告 VAR 變數後,VAR 成區域變數 global # 離開 func 後,VAR 變回全域變數 輸出
  66. 66. 匯出參數 66 export VAR=$1 $./exam.sh 11; echo $VAR # 執行完後,腳本內的 VAR 參數即消失 $source ./exam.sh 11; echo $VAR 11 # 使用 source 指令, 腳本內參數會保留 $. ./exam.sh 22; echo $VAR # 也可以用 . 來執行 22 輸出
  67. 67. 輸出重導 67 File Descriptor 說明 1 (預設) 標準輸出 (stdout) 2 標準錯誤輸出 (stderr) & (在 > 前時) 包含標準輸出及標準錯誤輸出 &<fd>(在 < 後時) 表示重導至 <fd> $ ls -l >stdout.txt # 把輸出結果寫到 stdout.txt $ ls -l /root >stderr.txt # 沒權限讀取 /root 目錄, # 標準錯誤輸出到 stderr.txt $ ls -l &>all.txt # 把標準輸出及標準錯誤輸出寫到 all.txt $ ls -l 1>&2 # 把標準輸出導至標準錯誤輸出
  68. 68. SHIFT 68 while (( "$#" )) do echo "$1 = $1, $@ = $@" shift done $./exam.sh 1 2 3 $1 = 1, $@ = 1 2 3 $1 = 2, $@ = 2 3 $1 = 3, $@ = 3 輸出 使用 shift 指令來左移輸入的參數

×