摘要:對fork,source和exec三種方式執行shell指令碼的總結。
準備知識
1.我們所執行的任何程式,都是由父進程(parent process)所產生出來的一個子進程(child process),子進程在結束後,將返回到父進程去。此一現像在Linux系統中被稱為 fork。當子進程被產生的時候,將會從父進程那裡獲得一定的資源分派、及(更重要的是)繼承父進程的環境﹗
2.Shell變數大致可以分為3種類型:
內部變數:系統提供,不用定義,不能修改,比如$#,$?,$*,$0等
環境變數:系統提供,不用定義,可以修改,當前進程及其子進程中使用,比如PATH,PWD,SHELL等
使用者變數(本地變數):使用者定義,可以修改,在當前進程使用,比如var=123等
與其他語言的區別:非類型性質,也就是不必指定變數是數字或字串等。
3.關於環境變數:環境變數只能從父進程到子進程單向繼承。換句話說:在子進程中的環境如何變更,均不會影響父進程的環境。
4.Shell指令碼:其實就是將你平時在Shell prompt後所輸入的多行command依序寫入一個檔案去而已
fork,source和exec方式執行Shell指令碼
fork方式
也就是常用的方式,一般在shell直接輸入指令檔路徑就可以了。這種方式由當前進程建立一個子進程
1: ./mytest.sh
source方式
使用方式如下(source與".”等價):
1: source ./mytest.sh
2: 或者
3: ../mytest.sh
source方式的特點是,在不另外建立子進程,而是在當前的的Shell環境中執行。
exec方式
1: exec./mytest.sh
此方式的特點是,不另外建立子進程,但是會終止當前的shell執行(其實我覺得這樣理解可能更準確:使用exec會在當前的進程空間建立一個子線程,然後終止當前線程的執行,到了建立的線程執行完之後,其實兩個線程都終止了,也就是這個當前shell進程也就終止了)
測試一
建立test1.sh,內容如下:
1: #!/bin/sh
2: cd~/bin
3: pwd
分別使用三種方式執行,source與exec方式都會將目錄更改應用到當前環境,不同的是,exec方式執行完之後,shell環境就不能夠使用了,會自動重啟一個新的shell環境(進程)
測試二
一個更為詳實的測試
指令碼1.sh
1: #!/bin/sh
2: A=B
3: echo"PID for 1.sh before exec/source/fork:$$"
4: exportA
5: echo"1.sh: /$A is $A"
6: case$1in
7: exec)
8: echo"using exec..."
9: exec./2.sh;;
10: source)
11: echo"using source..."
12: ../2.sh;;
13: *)
14: echo"using fork by default..."
15: ./2.sh;;
16: esac
17: echo"PID for 1.sh after exec/source/fork:$$"
18: echo"1.sh: /$A is $A"
指令碼2.sh
1: #!/bin/sh
2: echo"PID for 2.sh: $$"
3: echo"2.sh get /$A=$A from 1.sh"
4: A=C
5: exportA
6: echo"2.sh: /$A is $A"
分別使用三種方式執行1.sh指令碼,結果如下:
~$ ./1.sh fork
1: PID for 1.sh before exec/source/fork:531
2: 1.sh: $A is B
3: using fork by default...
4: PID for 2.sh:532
5: 2.sh get $A=B from 1.sh
6: 2.sh: $A is C
7: PID for 1.sh after exec/source/fork:531
8: 1.sh: $A is B
~$ ./1.sh source
1: PID for 1.sh before exec/source/fork:533
2: 1.sh: $A is B
3: using source...
4: PID for 2.sh:533
5: 2.sh get $A=B from 1.sh
6: 2.sh: $A is C
7: PID for 1.sh after exec/source/fork:533
8: 1.sh: $A is C
~$ ./1.sh exec
1: PID for 1.sh before exec/source/fork:537
2: 1.sh: $A is B
3: using exec...
4: PID for 2.sh:537
5: 2.sh get $A=B from 1.sh
6: 2.sh: $A is C
注意:使用exec執行時1.sh中最後兩句並沒有被執行
參考資料:
http://gaoyj1973.itpub.net/post/11309/498996
http://hi.baidu.com/cn_linux/blog/item/923cad8bf46cac7e9e2fb49d.html
http://blog.chinaunix.net/u2/63996/showart_573729.html
http://hi.baidu.com/252568175/blog/item/f3489918d585a80b34fa4143.html