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
注意: 主程序的剩下部分不执行了.