linux shell脚本中调用另一个shell脚本

曾经终败给现在 2021-07-28 17:58 1181阅读 0赞

先来说一下主要以下有几种方式:

1.fork: 如果脚本有执行权限的话,path/to/foo.sh。如果没有,sh path/to/foo.sh

2.exec: exec path/to/foo.sh

3.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

execfork 不同,不需要新开一个子 Shell 来执行被调用的脚本. 被调用的脚本与父脚本在同一个 Shell 内执行。但是使用 exec 调用一个新脚本以后, 父脚本中 exec 行之后的内容就不会再执行了。这是 execsource 的区别.

source

fork 的区别是不新开一个子 Shell 来执行被调用的脚本,而是在同一个 Shell 中执行. 所以被调用的脚本中声明的变量和环境变量, 都可以在主脚本中进行获取和使用。

实例

第一个脚本,我们命名为 1.sh:

  1. #!/usr/bin/env bash
  2. A=1
  3. echo "before exec/source/fork: PID for 1.sh = $$"
  4. export A
  5. echo "In 1.sh: variable A=$A"
  6. case $1 in
  7. --exec)
  8. echo -e "==> using exec…\n"
  9. exec ./2.sh ;;
  10. --source)
  11. echo -e "==> using source…\n"
  12. . ./2.sh ;;
  13. *)
  14. echo -e "==> using fork by default…\n"
  15. ./2.sh ;;
  16. esac
  17. echo "after exec/source/fork: PID for 1.sh = $$"
  18. echo -e "In 1.sh: variable A=$A\n"

第二个脚本,我们命名为 2.sh

  1. #!/usr/bin/env bash
  2. echo "PID for 2.sh = $$"
  3. echo "In 2.sh get variable A=$A from 1.sh"
  4. A=2
  5. export A
  6. echo -e "In 2.sh: variable A=$A\n"

注:这两个脚本中的参数 $$ 用于返回脚本的 PID , 也就是进程 ID。这个例子是想通过显示 PID 判断两个脚本是分开执行还是同一进程里执行,也就是是否有新开子 Shell。当执行完脚本 2.sh 后,脚本 1.sh 后面的内容是否还执行。

chmod +x 1.sh 2.sh 给两个脚本加上可执行权限后执行情况:

fork

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3doYXRkYXk_size_16_color_FFFFFF_t_70

fork方式可以看出,两个脚本都执行了,运行顺序为1-2-1,从两者的PID值(1.sh PID=82266, 2.sh PID=82267),可以看出,两个脚本是分成两个进程运行的。

exec

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3doYXRkYXk_size_16_color_FFFFFF_t_70 1

exec 方式运行的结果是,2.sh 执行完成后,不再回到 1.sh。运行顺序为 1-2。从pid值看,两者是在同一进程 PID=82287 中运行的。

source

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3doYXRkYXk_size_16_color_FFFFFF_t_70 2

source方式的结果是两者在同一进程里运行。该方式相当于把两个脚本先合并再运行。

三种方式对比:






















Command Explanation
fork 新开一个子 Shell 执行,子 Shell 可以从父 Shell 继承环境变量,但是子 Shell 中的环境变量不会带回给父 Shell。
exec 在同一个 Shell 内执行,但是父脚本中 exec 行之后的内容就不会再执行了
source 在同一个 Shell 中执行,在被调用的脚本中声明的变量和环境变量, 都可以在主脚本中进行获取和使用,相当于合并两个脚本在执行。

发表评论

表情:
评论列表 (有 0 条评论,1181人围观)

还没有评论,来说两句吧...

相关阅读

    相关 linux shell脚本

    不论是哪一种Shell,它最主要功能都是解译使用者的指令。类似windows中.bat `UNIX常用shell:` [http://blog.csdn.net/zhan