脚本exec
Ⅰ exec、source以及bash的区别
在bash shell中,source、exec以及sh都可以用来执行shell script,但是它们的差别在哪里呢?sh:父进程会fork一个子进程,shell script在子进程中执行source:在原进程中执行,不会fork子进程exec:在原进程中执行,但是同时会终止原进程 注:使用export会把父进程中的变量向子进程中继承,但是反过来却不行,在子进程中,不管环境如果改变,均不会影响父进程
下面用一个例子来讲解
[plain] view plain
1.sh
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"
[plain] view plain
2.sh
CODE:
echo "PID for 2.sh: $"
echo "2.sh get $A=$A from 1.sh"
A=C
export A
echo "2.sh: $A is $A"
下面在命令行中去执行
./1.sh fork
可以看到,1.sh是在父进程中执行,2.sh是在子进程中执行的,父进程的PID是5344,而子进程的是5345,当子进程执行完毕后,控制权返回到父进程。同时,在子进程改变环境变量A的值不会影响到父进程。
./1.sh source
由结果可知,1.sh和2.sh都是在同一进程中执行的,PID为5367
./1.sh exec
可知,两个脚本都是在同一进程中执行,但是请注意,使用exec终止了原来的父进程,因此,可以看到
[plain] view plain
echo "PID for 1.sh after exec/source/fork:$"
echo "1.sh: $A is $A"
这两个命令没有执行
由这个例子,便大致可了解它们的区别了
Ⅱ 执行shell脚本三种方法的区别:(sh、exec、source)
使用$ sh script.sh执行脚本时,当前shell是父进程,生成一个子shell进程,在子shell中执行脚本。脚本执行完毕,退出子shell,回到当前shell。
./script.sh与 sh script.sh等效。
使用$ source script.sh方式,在当前上下文中执行脚本,不会生成新的进程。脚本执行完毕,回到当前shell。
source方式也叫点命令。
. script.sh与 source script.sh等效。
使用exec command方式,会用command进程替换当前shell进程,并且保持PID不变。执行完毕,直接退出,不回到之前的shell环境。
二、测试验证
vi loop.sh
显示当前进程
sh的方式:执行loop.sh打印执行进程
source方式:执行loop.sh打印执行进程
exec方式:执行loop.sh打印执行进程
按下ctrl+C
sh方式:父进程是6770,执行loop.sh时的子进程是13736。执行完毕后回到父进程shell。
source方式:父进程和子进程都是6770(执行时没有新的进程),执行完毕会回到父进程shell。
exec方式:进程PID没有改变都是6770,执行完毕(ctrl+C强制关闭)时直接退出了shell。脚本执行时替换了父进程的shell,执行完毕后直接退出,没有回到之前的shell。
Ⅲ shell脚本中的 exec 命令
exec执行命令时,不会启用新的shell进程。
source和 .也不会启用新的shell进程,在当前shell中执行,设定的局部变量在执行完命令后仍然有效。
bash或sh执行时,会另起一个子shell进程,其继承父shell进程的环境变量,其子shell进程的变量执行完后不影响父shell进程。
exec是用被执行的命令行替换掉当前的shell进程,且exec命令后的其他命令将不再执行。
例如在当前shell中执行 exec ls 表示执行ls这条命令来替换当前的shell ,即为执行完后会退出当前shell。
为了避免父shell被退出,一般将exec命令放到一个子shell脚本中,在父sehll中调用这个子shell脚本,调用处可以用bash xx.sh(xx.sh为存放exec命令的脚本),这样会为xx.sh建立一个子shell去执行,当执行exec后该子shell进程就被替换成相应的exec的命令。
其中有一个例外:当exec命令对文件描述符操作的时候,就不会替换shell,而是操作完成后还会继续执行后面的命令!
文件描述符
shell中描述符一共有12个
0 代表标准输入
1 代表标准输出
2 错误输出
其他 3-9 都是空白描述符
其含义是: 复制标准输出到3 ,错误输出到 4 ,把 3 4 保存在bash.log 这个文件中。
其含义是:将bash.sh脚本执行的标准输出和错误输出追加重定向到 bash.log
如果exec 跟的是其他命令,则其他命令结束后,本shell也随之停止
可以看到随着 echo " hello oracle" 这条指令运行完本 整个脚本执行完毕,后面的 echo " hello db2" 没有执行!
二、Linux shell 脚本中, $@ 和 $@ 分别是什么意思?
$@ 表示所有脚本参数的内容
$# 表示返回所有脚本参数的个数
示例:编写如下shell脚本,保存为test.sh
说明:给脚本提供了两个参数,所以 @代表了参数的内容!
怎么理解shell脚本中 exec "`dirname "$0"`/node""$0" "$@" ?
$0 #脚本自己的路径
"`dirname "$0"`"/node #脚本目录下的node程序的路径
$@ #脚本被执行时的命令行参数
合起来就是:用脚本目录下的node程序来解释这个脚本本身
exec scala "$0" "$@" 是什么意思
这是bash语法。
$0 #表示当前脚本的名字
$@ #表示当前脚本执行的所有参数
exec scala "$0" "$@" #表示用scala命令,带参数,执行当前脚本
$0 是位置参数,表示脚本名称
$1 表示脚本的第一个参数,依次类推直到 $9
exec用于执行命令、或脚本、或外部可执行程序,会新建一个shell去执行
综上,这里exec sh "$0" 就是执行脚本本身
所以,就是一个循环过程,每隔两秒打印一次 Hello