1. 程式人生 > >shell指令碼學習--符號

shell指令碼學習--符號

由上例可看到
  • 指令碼檔案可以一次執行多條命令。
  • cd .. 進入上級目錄列印了上級目錄的路徑,但是並沒有進入到上級目錄下。(原因在下面)
     除chmod+x執行指令碼外,還可以/bin/bash my_script.sh執行指令碼 2、 指令碼的執行過程      shell會fork一個子程序並呼叫exec執行./my_script.sh這個程式,exec系統呼叫把子程序的程式碼替換成shell指令碼程式的程式碼段,並從它的_start開始執行。但是這個指令碼.sh檔案是個指令碼檔案,根本沒有程式碼段和_start函式。所以exec會執行另一種機制。      由於第一行用shebang指定了直譯器,則用直譯器程式程式碼替換當前程序,並且從直譯器的_start開始,這個文字檔案被當做命令列引數傳給直譯器
*解釋型語言只需要直譯器解釋,不需要編譯器,如shell指令碼語言;C語言是編譯型語言 在上面的例子中,cd.. 後仍在當前目錄的原因:
  • 互動式shell(命令列)fork/exec一個子shell用於執行指令碼,父程序讓子程序去執行命令,父程序在後臺等待子程序退出在返回前臺。
  • 子程序讀取指令碼中的cd .. 命令,呼叫相應的函式執行內建命令,改變當前工作目錄為上一級目錄(子程序)
  • 子程序讀取指令碼中pwd命令,fork/exec這個程式,列出當前路徑,子程序等待pwd終止
  • pwd終止後,子程序繼續執行,讀到指令碼檔案末尾終止。
  • 子程序終止後,bash繼續執行,列印提示符等待使用者輸入
*若將命令列下輸入的命令用()括號括起來,也會fork出一個子shell執行小括號中的命令,命令列一行中也可以輸入由分號;隔開的多個命令。
     對於內建命令,在互動式shell下輸入則可以由自己l執行,如在命令列下輸入cd .. 則進入上級目錄。若識別不是內建命令,則派生子程序,子程序exec,父程序得到結果。      若想讓內建的命令不建立子shell,直接在互動式shell下逐行執行指令碼中命令:
  •      在執行./my_sscript.sh時,在前面加source:$source ./my_script.sh
  •      在執行./my_sscript.sh時,在前面加 . :$. ./my_script.sh
二、shell變數 1、環境變數      環境變數可以從父程序傳給子程序,所以shell程序的環境變數可以從當前的shell程序傳給fork出來的子程序,用printenv可以顯示當前shell程序的環境變數。 *fork函式得到的子程序從父程序繼承了整個程序的地址空間,包括:程序上下文、程序堆疊、記憶體資訊、開啟的檔案描述符、訊號控制設定、程序優先順序、程序組號、當前工作目錄、根目錄。資源限制、控制終端、環境變數等。但是父程序設定的鎖子程序不繼承且子程序的未決訊號集被設定為空集。
2、本地變數      只存在當前shell程序,用set命令可以顯示當前shell程序中定義的所有變數,包括本地和環境變數。      當定義環境變數時,等號的兩邊不能有空格,否則會被shell解釋為命令和命令列引數。一個變數定義後進存在當前shell程序,是本地變數,用export可以把本地變數匯出為環境變數。      用unset可以刪除已定義的環境變數      VARNAME=value  #定義本地變數      export  VARNAME=value  #匯出本地變數,也可以寫為VARNAME=value; export  VARNAME      unset VARNAME    #刪除已定義的環境變數或本地變數 3、變數引用      echo ${變數名}      在不引起歧異的情況下也可以用 $變數名 來表示。      如:           echo $變數名aaa   #引起歧異,需要加上花括號      shell變數不需要定義明確型別,因為shell變數都是字串,對一個沒有定義的變數取值則值為空字串。 三、替換 1、檔名替換 1、萬用字元 * :匹配0個或任意多個字元 2、 ? :問好匹配一個任意字元 3、[] :方括號,匹配括號中任意一個字元的一次出現。 2、命令替換 1、$() :由括號括起來的也是一條命令,shell先執行括號內命令,然後輸出結果立刻替換到當前命令列中。 2、'    :反引號同上。  mytime=$(data +%y-%M-%d)          #或  mytime=$'data +%y-%M-%d)'  echo $mytime *$()和''的區別:
  • ''在執行時,shell不管''內是什麼都先進行解釋,然後把解釋後的最終結果送給shell去執行,若解釋後的最終結果不是shell可執行的命令時,則會出錯,僅把單引號執行後的內容作為文字輸出。
  • $()在執行時,若括號中是命令則直接丟給shell執行,若是變數取值,則僅做第一層的字面意思解釋丟給shell執行。
  • ‘’產生的結果不會再給shel解釋,而只作為賦值直接使用。$()在產生結果後還會進一步解釋
          3、$(()):算數替換,用於算數計算,$(())中的shell變數取值將轉換成整數           $ VAR=45           $ echo $((VAR+3))           $(())中只能用加減乘除和()運算子,且只能做整數運算
四、轉義字元      \反斜槓被用作轉義字元,用於去除緊跟其後的單個字元的特殊意義。 例;      touch $ $               #建立一個名為    $的檔案      touch \$\ \$           #建立一個名為     $ $的檔案(中間有空格)   對於-開頭的檔案,由於一般-開頭的是命令列引數的選項,所以/也不能將其轉義,若非要-開頭,則:      touch ./-hello     #前面加上當前路徑      touch -- -file      #前面加上兩個--  五、符號 1、單引號和雙引號      在c中分別表示字元和字串,在shell中均表示字串,但是單引號對裡面的內容直接輸出,雙引號允許替換。      雙引號中$加變數名可以取變數的值,\$表示$的字面值,\'表示 ' 的字面值,\\表示\的字面值