fork,source和exec運行腳本時的差異
使用 fork 方式運行 script 時, 就是讓 shell(parent process) 產生一個 child process 去執行該 script, 當 child process 結束後, 會返回 parent process, 但 parent process 的環境是不會因 child process 的改變而改變的.
source
使用 source 方式運行 script 時, 就是讓 script 在當前 process 內執行, 而不是產生一個 child process 來執行. 由於所有執行結果均於當前 process 內完成, 若 script 的環境有所改變, 當然也會改變當前 process 環境了.
exec
使用 exec 方式運行script時, 它和 source 一樣, 也是讓 script 在當前process內執行, 但是 process 內的原代碼剩下部分將被終止. 同樣, process 內的環境隨script 改變而改變.
結論:通常如果我們執行時,都是默認為fork的。大家可以通過pstree命令看看關於父子進程的關系。如上,如果想讓父進程得到子進程的環境變量,就是source方式了
1.sh的腳本
[sql]
#!/bin/bash
A=B
echo "PID for 1.sh before exec/source/fork:$$"
export A
echo "1.sh: \$A is $A"
case $1 in
exec)
echo "using exec…"
exec ./2.sh ;;
source)
echo "using source…"
. ./2.sh ;;
*)
echo "using fork by default…"
./2.sh ;;
esac
echo "PID for 1.sh after exec/source/fork:$$"
echo "1.sh: \$A is $A"
2.sh的腳本
[sql]
#!/bin/bash
echo "PID for 2.sh: $$"
echo "2.sh get \$A=$A from 1.sh"
A=C
export A
echo "2.sh: \$A is $A"
3. 實驗
3.1 fork
[sql]
PID for 1.sh before exec/source/fork:25992
1.sh: $A is B
using fork by default…
PID for 2.sh: 25993
2.sh get $A=B from 1.sh
2.sh: $A is C
PID for 1.sh after exec/source/fork:25992
1.sh: $A is B
3.2 source
[sql]
PID for 1.sh before exec/source/fork:25994
1.sh: $A is B
using source…
PID for 2.sh: 25994
2.sh get $A=B from 1.sh
2.sh: $A is C
PID for 1.sh after exec/source/fork:25994
1.sh: $A is C
注意: 三個PID都是25994, 子程序的環境變量被帶了出來.
3.3 exec
[sql]
PID for 1.sh before exec/source/fork:25997
1.sh: $A is B
using exec…
PID for 2.sh: 25997
2.sh get $A=B from 1.sh
2.sh: $A is C
注意: 主程序的剩下部分不執行了.