Linux Shell編程零基礎(chǔ)入門

  從程序員的角度來看,

Shell本身是一種用C語言編寫的程序,從用戶的角度來看,Shell是用戶與Linux操作系統(tǒng)溝通的橋梁。用戶既可以輸入命令執(zhí)行,又可以利用

Shell腳本編程,完成更加復(fù)雜的操作。在Linux

GUI日益完善的今天,在系統(tǒng)管理等領(lǐng)域,Shell編程仍然起著不可忽視的作用。深入地了解和熟練地掌握Shell編程,是每一個Linux用戶的必修

功課之一。

  Linux的Shell種類眾多,常見的有:Bourne Shell(/usr/bin/sh或/bin/sh)、Bourne Again

Shell(/bin/bash)、C Shell(/usr/bin/csh)、K Shell(/usr/bin/ksh)、Shell for

Root(/sbin/sh),等等。不同的Shell語言的語法有所不同,所以不能交換使用。每種Shell都有其特色之處,基本上,掌握其中任何一種

就足夠了。在本文中,我們關(guān)注的重點是Bash,也就是Bourne Again

Shell,由于易用和免費,Bash在日常工作中被廣泛使用;同時,Bash也是大多數(shù)Linux系統(tǒng)默認的Shell。在一般情況下,人們并不區(qū)分 Bourne

Shell和Bourne Again Shell,所以,在下面的文字中,我們可以看到#!/bin/sh,它同樣也可以改為#!/bin/bash。

  利用vi等文本編輯器編寫Shell腳本的格式是固定的,如下:

  #!/bin/sh

  #comments

  Your commands go here

  首行中的符號#!告訴系統(tǒng)其后路徑所指定的程序即是解釋此腳本文件的Shell程

序。如果首行沒有這句話,在執(zhí)行腳本文件的時候,將會出現(xiàn)錯誤。后續(xù)的部分就是主程序,Shell腳本像高級語言一樣,也有變量賦值,也有控制語句。除第

一行外,以#開頭的行就是注釋行,直到此行的結(jié)束。如果一行未完成,可以在行尾加上",這個符號表明下一行與此行會合并為同一行。

  編輯完畢,將腳本存盤為filename.sh,文件名后綴sh表明這是一個Bash腳本文件。執(zhí)行腳本的時候,要先將腳本文件的屬性改為可執(zhí)行的:

  chmod +x filename.sh

  執(zhí)行腳本的方法是:

  ./filename.sh

  下面我們從經(jīng)典的“hello world”入手,看一看最簡單的Shell腳本的模樣。

  #!/bin/sh

  #print hello world in the console window

  a = "hello world"

  echo $a

  Shell

Script是一種弱類型語言,使用變量的時候無需首先聲明其類型。新的變量會在本地數(shù)據(jù)區(qū)分配內(nèi)存進行存儲,這個變量歸當前的Shell所有,任何子進

程都不能訪問本地變量。這些變量與環(huán)境變量不同,環(huán)境變量被存儲在另一內(nèi)存區(qū),叫做用戶環(huán)境區(qū),這塊內(nèi)存中的變量可以被子進程訪問。變量賦值的方式是:

  variable_name = variable_value

  如果對一個已經(jīng)有值的變量賦值,新值將取代舊值。取值的時候要在變量名前加$,$variable_name可以在引號中使用,這一點和其他高級語言是明顯不同的。如果出現(xiàn)混淆的情況,可以使用花括號來區(qū)分,例如:

  echo "Hi, $as"

  就不會輸出“Hi, hello

worlds”,而是輸出“Hi,”。這是因為Shell把$as當成一個變量,而$as未被賦值,其值為空。正確的方法是:

  echo "Hi, ${a}s"

  單引號中的變量不會進行變量替換操作。

  關(guān)于變量,還需要知道幾個與其相關(guān)的Linux命令。

  env用于顯示用戶環(huán)境區(qū)中的變量及其取值;set用于顯示本地數(shù)據(jù)區(qū)和用戶環(huán)境區(qū)中的變量及其取值;unset用于刪除指定變量當前的取值,該值將被指定為NULL;export命令用于將本地數(shù)據(jù)區(qū)中的變量轉(zhuǎn)移到用戶環(huán)境區(qū)。

  下面我們來看一個更復(fù)雜的例子,結(jié)合這個例子,我們來講述Shell Script的語法。

  1 #!/bin/bash

  2 # we have less than 3 arguments. Print the help text:

  3 if [ $# -lt 3 ]; then

  4 cat<

  5 ren -- renames a number of files using sed regular expressions

  6

  7 USAGE: ren 'regexp' 'replacement' files

  8 EXAMPLE: rename all *.HTM files in *.html:

  9 ren 'HTM$' 'html' *.HTM

  10

  11 HELP

  12 exit 0

  13 fi

  14 OLD="$1"

  15 NEW="$2"

  16 # The shift command removes one argument from the list of

  17 # command line arguments.

  18 shift

  19 shift

  20 # $* contains now all the files:

  21 for file in $*; do

  22 if [ -f "$file" ]; then

  23 newfile=`echo "$file" | sed "s/${OLD}/${NEW}/g"`

  24 if [ -f "$newfile" ]; then

  25 echo "ERROR: $newfile exists already"

  26 else

  27 echo "renaming $file to $newfile

  "

  28 mv "$file" "$newfile"

  29 fi

  30 fi

  31 done

  我們從頭來看,前面兩行上一個例子中已經(jīng)解釋過了,從第三行開始,有新的內(nèi)容。if語句和其他編程語言相似,都是流程控制語句。它的語法是:

  if …; then

  …

  elif …; then

  …

  else

  …

  fi

  與其他語言不同,Shell Script中if語句的條件部分要以分號來分隔。第三行中的[]表示條件測試,常用的條件測試有下面幾種:

  [ -f "$file" ] 判斷$file是否是一個文件

  [ $a -lt 3 ] 判斷$a的值是否小于3,同樣-gt和-le分別表示大于或小于等于

  [ -x "$file" ] 判斷$file是否存在且有可執(zhí)行權(quán)限,同樣-r測試文件可讀性

  [ -n "$a" ] 判斷變量$a是否有值,測試空串用-z

  [ "$a" = "$b" ] 判斷$a和$b的取值是否相等

  [ cond1 -a cond2 ] 判斷cond1和cond2是否同時成立,-o表示cond1和cond2有一成立

  要注意條件測試部分中的空格。在方括號的兩側(cè)都有空格,在-f、-lt、=等符號兩側(cè)同樣也有空格。如果沒有這些空格,Shell解釋腳本的時候就會出錯。

  $#表示包括$0在內(nèi)的命令行參數(shù)的個數(shù)。在Shell中,腳本名稱本身是$0,剩下的依次是$0、$1、$2…、${10}、${11},等等。$*表示整個參數(shù)列表,不包括$0,也就是說不包括文件名的參數(shù)列表。

  現(xiàn)在我們明白第三行的含義是如果腳本文件的參數(shù)少于三個,則執(zhí)行if和fi語句之間 的內(nèi)容。然后,從第四行到第十一行之間的內(nèi)容在Shell

Script編程中被稱為Here文檔,Here文檔用于將多行文本傳遞給某一命令。Here文檔的格式是以<<開始,后跟一個字符串,在

Here文檔結(jié)束的時候,這個字符串同樣也要出現(xiàn),表示文檔結(jié)束。在本例中,Here文檔被輸出給cat命令,也即將文檔內(nèi)容打印在屏幕上,起到顯示幫助

信息的作用。

  第十二行的exit是Linux的命令,表示退出當前進程。在Shell腳本中可以使用所有的Linux命令,利用上面的cat和exit,從一方面來說,熟練使用Linux命令也可以大大減少Shell腳本的長度。

  十四、十五兩句是賦值語句,分別將第一和第二參數(shù)賦值給變量OLD和NEW。緊接下來的兩句是注釋,注釋下面的兩條shift的作用是將參數(shù)列表中的第一個和第二個參數(shù)刪除,后面的參數(shù)依次變?yōu)樾碌牡谝缓偷诙?shù),注意參數(shù)列表原本也不包括$0。

  然后,自二十一行到三十一行是一個循環(huán)語句。Shell Script中的循環(huán)有下面幾種格式:

  while [ cond1 ] && { || } [ cond2 ] …; do

  …

  done

  for var in …; do

  …

  done

  for (( cond1; cond2; cond3 )) do

  …

  done

  until [ cond1 ] && { || } [ cond2 ] …; do

  …

  done

  在上面這些循環(huán)中,也可以使用類似C語言中的break和continue語句中斷

當前的循環(huán)操作。第二十一行的循環(huán)是將參數(shù)列表中的參數(shù)一個一個地放入變量file中。然后進入循環(huán),判斷file是否為一個文件,如果是文件的話,則用

sed命令搜索和生成新的文件名。sed基本上可以看成一個查找替換程序,從標準輸入,例如管道讀入文本,并將結(jié)果輸出到標準輸出,sed使用正則表達式

進行搜索。在第二十三行中,backtick(`)的作用是取出兩個backtick之間的命令輸出結(jié)果,在這里,也就是將結(jié)果取出賦給變量

newfile。此后,判斷newfile是否已經(jīng)存在,否則就把file改成newfile。這樣我們就明白這個腳本的作用了,Shell

Script編寫的其他腳本與此相似,只不過是語法和用法稍有不同而已。

  通過這個例子我們明白了Shell Script的編寫規(guī)則,但還有幾件事情需要講述一下。

  第一個,除了if語句之外,Shell Script中也有類似C語言中多分支結(jié)構(gòu)的case語句,它的語法是:

  case var in

  pattern 1 )

  … ;;

  pattern 2 )

  … ;;

  *)

  … ;;

  esac

  我們再就下面一個例子,看看case語句的用法。

  while getopts vc: OPTION

  do

  case $OPTION in

  c) COPIES=$OPTARG

  ehco "$COPIES";;

  v) echo "suyang";;

  \?) exit 1;;

  esac

  done

  上面的getopts類似于C語言提供的函數(shù)getopts,在Shell

Script中,getopts經(jīng)常和while語句聯(lián)合起來使用。getopts的語法如下:

  getopts option_string variable

  option_string中包含一串單字符選項,若getopts在命令行參數(shù)中

發(fā)現(xiàn)了連字符,那么它會將連字符之后的字符與option_string進行比較,若匹配成功,則把變量variable的值設(shè)為該選項,若無匹配,則把

變量的值設(shè)為?。有時候,選項還會帶一個值,例如-c5等,這時要在option_string中該選項字母后面加上一個冒號,getopts發(fā)現(xiàn)冒號

后,會讀取該值,然后將該值放入特殊變量OPTARG中。這個命令比較復(fù)雜,如有需要,讀者可以詳細參閱Shell編寫的相關(guān)資料。

  上面這個循環(huán)的作用就是依次取出腳本名稱后面的選項,進行處理,如果輸入了非法選項,則進入"?指定的部分,退出腳本程序。

  第二個,Bash提供了一種用于交互式應(yīng)用的擴展select,用戶可以從一組不同的值中進行選擇。其語法如下:

  select var in …; do

  break;

  done

  例如,下面這段程序的輸出是:

  #!/bin/bash

  echo "Your choice?"

  select var in "a" "b" "c"; do

  break

  done

  echo $var

  ----------------------------

  Your choice?

  1) a

  2) b

  3) c

  第三,Shell Script中也可以使用自定義的函數(shù),其語法形式如下:

  functionname()

  {

  …

  }

  例如我們可以把上面第二個例子中第四到第十二行放入一個名為help函數(shù)體內(nèi),以后每次調(diào)用的時候直接寫help即可。函數(shù)中處理函數(shù)調(diào)用參數(shù)的方法是,直接用上面講過的$1、$2來分別表示第一、第二個參數(shù),用$*表示參數(shù)列表。

  第四,我們也可以在Shell下調(diào)試Shell

Script腳本,當然最簡單的方法就是用echo輸出查看變量取值了。Bash也提供了真正的調(diào)試方法,就是執(zhí)行腳本的時候用-x參數(shù)。

  sh ?x filename.sh

  這會執(zhí)行腳本并顯示腳本中所有變量的取值,也可以使用參數(shù)-n,它并不執(zhí)行腳本,只是返回所有的語法錯誤。

  -----------------------------------------------------------------------------------------------------------------------------------------------

  下方是Linux相關(guān)的一些視頻資料可以來學習參考

  shell腳本快速入門

  http://www.makeru.com.cn/live/3485_1489.html?s=45051

  單鏈表

  http://www.makeru.com.cn/live/5413_1924.html?s=45051

  linux基礎(chǔ)

  http://www.makeru.com.cn/course/details/2058?s=45051

  快速上手linux

  http://www.makeru.com.cn/live/1758_310.html?s=45051

  Linux網(wǎng)絡(luò)經(jīng)典案例

  http://www.makeru.com.cn/live/3485_1630.html?s=45051

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容