shell中的fork、source和exec總結(包括環境變量)


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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM