在linux 里做一件事的方法往往有很多种,比如执行一个脚本的就有很多种方式,那么这些方式有什么区别呢?
首先,执行一个shell 脚本的方法有以下几种:source sh ./ bash ,那么这些方式有什么区别呢?它们的区别主要是在当前shell环境中运行还是另外开启一个子shell运行以及运行该shell对当前shell环境的影响。
1 source
source 是在当前shell环境下读取该文件的内容,并执行该脚本里的语句,运行结果会影响当前shell的环境,该命令并不会重新启动一个子进程去执行该脚本。
[make@master test]$ echo $$
16575
[make@master test]$ vi s
#!/usr/bin/env bash
echo $$
[make@master test]$ source s
16575
[make@master test]$
由此可见运行shell的进程和当前shell的进程是一样的。
如果修改了 /etc/profile 文件,想让修改立即生效用source命令即可:
source /etc/profile
source 可以简写成 .
2 sh bash
这两个命令均是linux的命令,意思是开启一个子进程去执行该脚本。因为是子进程,所以该脚本并不会对当前环境产生影响。
3 ./
这个需要该脚本具有可执行的权限,也是开启一个子进程去执行脚本。上面讲述的几个命令均不需要脚本具有可执行权限。
4、fork、source、exec
- 使用fork方式运行script时, 就是让shell(parent process)产生一个child process去执行该script,当child process结束后,会返回parent process,但parent process的环境是不会因child process的改变而改变的。
- 使用source方式运行script时, 就是让script在当前process内执行, 而不是产生一个child process来执行。由于所有执行结果均于当前process内完成,若script的环境有所改变, 当然也会改变当前process环境了。
- 使用exec方式运行script时, 它和source一样,也是让script在当前process内执行,但是process内的原代码剩下部分将被终止。同样,process内的环境随script改变而改变。
通常如果我们执行时,都是默认为fork的。
为了实践下,我们可以先建立2个sh文件,1.sh
#!/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
#!/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"
运行下面命令观察结果:
chmod +x 1.sh
chmod +x 2.sh
./1.sh fork
./1.sh source
./1.sh exec
参考:http://www.cnblogs.com/pcat/p/5467188.html