在Shell脚本中调⽤另⼀个Shell脚本的三种⽅式
在 Shell 脚本中调⽤另⼀个 Shell 脚本的三种⽅式
先来说⼀下主要以下有⼏种⽅式:
fork: 如果脚本有执⾏权限的话,path/to/foo.sh。如果没有,sh path/to/foo.sh。
exec: exec path/to/foo.sh
source: source path/to/foo.sh
fork
fork 是最普通的, 就是直接在脚本⾥⾯⽤ path/to/foo.sh 来调⽤foo.sh 这个脚本,⽐如如果是 foo.sh 在当前⽬录下,就是 ./foo.sh。运⾏的时候 terminal 会新开⼀个⼦ Shell 执⾏脚本 foo.sh,⼦ Shell 执⾏的时候, ⽗ Shell 还在。⼦ Shell 执⾏完毕后返回⽗ Shell。 ⼦ Shell 从⽗ Shell 继承环境变量,但是⼦ Shell 中的环境变量不会带回⽗ Shell。
exec
exec 与 fork 不同,不需要新开⼀个⼦ Shell 来执⾏被调⽤的脚本. 被调⽤的脚本与⽗脚本在同⼀个 Shell 内执⾏。但是使⽤ exec 调⽤⼀个新脚本以后, ⽗脚本中 exec ⾏之后的内容就不会再执⾏了。这是 exec 和 source 的区别.
source
与 fork 的区别是不新开⼀个⼦ Shell 来执⾏被调⽤的脚本,⽽是在同⼀个 Shell 中执⾏. 所以被调⽤的脚本中声明的变量和环境变量, 都可以在主脚本中进⾏获取和使⽤。shell脚本返回执行结果
其实从命名上可以感知到其中的细微区别,下⾯通过两个脚本来体会三种调⽤⽅式的不同:
第⼀个脚本,我们命名为 1.sh:
#!/usr/bin/env bash
A=1
echo "before exec/source/fork: PID for 1.sh = $$"
export A
echo "In 1.sh: variable A=$A"
case $1 in
--exec)
echo -e "==> using exec…\n"
exec ./2.sh ;;
--source)
echo -e "==> using source…\n"
../2.sh ;;
*)
echo -e "==> using fork by default…\n"
./2.sh ;;
esac
echo "after exec/source/fork: PID for 1.sh = $$"
echo -e "In 1.sh: variable A=$A\n"
第⼆个脚本,我们命名为 2.sh:
#!/usr/bin/env bash
echo "PID for 2.sh = $$"
echo "In 2.sh get variable A=$A from 1.sh"
A=2
export A
echo -e "In 2.sh: variable A=$A\n"
注:这两个脚本中的参数 $$ ⽤于返回脚本的 PID , 也就是进程 ID。这个例⼦是想通过显⽰ PID 判断两
个脚本是分开执⾏还是同⼀进程⾥执⾏,也就是是否有新开⼦ Shell。当执⾏完脚本 2.sh 后,脚本 1.sh 后⾯的内容是否还执⾏。
chmod +x 1.sh 2.sh 给两个脚本加上可执⾏权限后执⾏情况:
$ ./1.sh
PID for1.sh before exec/source/fork:5845
1.sh: $A is B
using fork by default…
PID for2.sh:5242
2.sh get $A=B from 1.sh
2.sh: $A is C
PID for1.sh after exec/source/fork:5845
1.sh: $A is B
fork⽅式可以看出,两个脚本都执⾏了,运⾏顺序为1-2-1,从两者的PID值,可以看出,两个脚本是分成两个进程运⾏的。
$ ./1.sh exec
PID for1.sh before exec/source/fork:5562
1.sh: $A is B
using exec…
PID for2.sh:5562
2.sh get $A=B from 1.sh
2.sh: $A is C
exec⽅式运⾏的结果是,2执⾏完成后,不再回到1。运⾏顺序为1-2。从pid值看,两者是在同⼀进程中运⾏的。
$ ./1.sh source
PID for1.sh before exec/source/fork:5156
1.sh: $A is B
using source…
PID for2.sh:5156
2.sh get $A=B from 1.sh
2.sh: $A is C
PID for1.sh after exec/source/fork:5156
1.sh: $A is C
source⽅式的结果是两者在同⼀进程⾥运⾏。该⽅式相当于把两个脚本先合并再运⾏。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。