摘要:對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