如下:

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

1、fork

fork 是最普通的, 就是直接在脚本里面用 path/to/foo.sh 来调用
foo.sh 这个脚本,比如如果是 foo.sh 在当前目录下,就是 ./foo.sh。运行的时候 terminal 会新开一个子 Shell 执行脚本 foo.sh,子 Shell 执行的时候, 父 Shell 还在。子 Shell 执行完毕后返回父 Shell。 子 Shell 从父 Shell 继承环境变量,但是子 Shell 中的环境变量不会带回父 Shell。

2、exec

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

3、source

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

测试

脚本1、父脚本

#!/usr/bin/env bash

A=

echo "执行调用之前进程Id exec/source/fork: PID for 1.sh = $$"

export A
echo "In 1.sh: variable A=$A" case $ in
--exec)
echo -e "==> using exec…\n"
exec ./.sh ;;
--source)
echo -e "==> using source…\n"
. ./.sh ;;
*)
echo -e "==> using fork by default…\n"
./.sh ;;
esac echo "执行调用之后进程Id exec/source/fork: PID for 1.sh = $$"
echo -e "父脚本1.sh: variable A=$A\n"

脚本2、子脚本

#!/usr/bin/env bash

echo "子脚本2PID for 2.sh = $$"
echo "In 2.sh get variable A=$A from 1.sh" A=
export A echo -e "子脚本2.sh默认A=2: variable A=$A\n"

测试一、fork方式,直接调用

$ ./1.sh
执行调用之前进程Id exec/source/fork: PID for .sh =
In .sh: variable A=
==> using fork by default… 子脚本2PID for .sh =
In .sh get variable A= from .sh
子脚本2.sh默认A=: variable A= 执行调用之后进程Id exec/source/fork: PID for .sh =
In .sh: variable A=

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

测试二、exec方式:./1.sh exec

$ ./1.sh exec
执行调用之前进程Id exec/source/fork: PID for .sh =
In .sh: variable A=
==> using exec… 子脚本2PID for .sh =
In .sh get variable A= from .sh
子脚本2.sh默认A=: variable A=

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

测试三、source方式:./1.sh source

$ ./1.sh source
执行调用之前进程Id exec/source/fork: PID for .sh =
In .sh: variable A=
==> using source… 子脚本2PID for .sh =
In .sh get variable A= from .sh
子脚本2.sh默认A=: variable A= 执行调用之后进程Id exec/source/fork: PID for .sh =
父脚本1.sh: variable A=

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

对比

Command 进程 变量 Explanation
fork 父子不同进程 子继承父变量,子不能传递给父

新开一个子 Shell 执行,当子进程执行完毕后会返回父进程,但是父进程的环境变量不会因子进程的改变而改变。

子 Shell 可以从父 Shell 继承环境变量,但是子 Shell 中的环境变量不会带回给父 Shell。

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

脚本地址:https://github.com/bjlhx15/shell.git 下的test/invokesh

013-在 Shell 脚本中调用另一个 Shell 脚本的三种方式的更多相关文章

  1. Shell 脚本中调用另一个 Shell 脚本的三种方式

    主要以下有几种方式: Command Explanation fork 新开一个子 Shell 执行,子 Shell 可以从父 Shell 继承环境变量,但是子 Shell 中的环境变量不会带回给父 ...

  2. 在一个JSP页面中包含另一个JSP页面的三种方式

    转载自://http://blog.163.com/neu_lxb/blog/static/179417010201121343132918/ (1)include指令          includ ...

  3. 在一个py脚本中调用另外一个py脚本中的类或函数

    1.两个文件在同一目录,直接import即可 2.两个文件在不同目录 在导入文件的时候,Python只搜索当前脚本所在的目录,加载(entry-point)入口脚本运行目录和sys.path中包含的路 ...

  4. shell脚本中执行另一个shell脚本

    分类: 可以在一个shell脚本中执行另一个shell脚本(或非可执行文件,主要用于取得一些变量的值),方法是: . 文件名(包括路径) 或 变量=文件名(包括路径) . $变量   注意,圆点后面有 ...

  5. ASP.NET MVC中使用Unity进行依赖注入的三种方式

    在ASP.NET MVC中使用Unity进行依赖注入的三种方式 2013-12-15 21:07 by 小白哥哥, 146 阅读, 0 评论, 收藏, 编辑 在ASP.NET MVC4中,为了在解开C ...

  6. Shell脚本中调用另外一个脚本的方法

    (转载): 在Linux平台上开发,经常会在console(控制台)上执行另外一个脚本文件,经常用的方法有:./my.sh 或 source my.sh 或 . my.sh:这三种方法有什么不同呢?我 ...

  7. Mybatis-plus中如何排除非表字段的三种方式

    1.transient关键字 2.使用静态变量(static) 3.TableField(exit=false) 这三种方式可以在使用的过程中,是这个对象中的属性不被序列化.(直接被忽略)

  8. shell脚本中调用另一个脚本的三种不同方法(fork, exec, source)

    fork ( /directory/script.sh) fork是最普通的, 就是直接在脚本里面用/directory/script.sh来调用script.sh这个脚本. 运行的时候开一个sub- ...

  9. 在shell脚本中调用另一个脚本的三种不同方法(fork, exec, source)——转载

    原文链接:http://blog.chinaunix.net/uid-22548820-id-3181798.html fork ( /directory/script.sh) :如果shell中包含 ...

随机推荐

  1. linux设备驱动程序-i2c(1):i2c总线的添加与实现

    linux设备驱动程序-i2c(1):i2c总线的添加与实现 (基于4.14内核版本) 在上一章节linux设备驱动程序-i2c(0)-i2c设备驱动源码实现中,我们演示了i2c设备驱动程序的源码实现 ...

  2. HikariCP 个人实例

    pom依赖 <!--HikariCP数据库连接池--> <dependency> <groupId>com.zaxxer</groupId> <a ...

  3. 微信小程序~扫码

    为了让用户减少输入,我们可以把复杂的信息编码成一个二维码,利用宿主环境wx.scanCode这个API调起微信扫一扫,用户扫码之后,wx.scanCode的success回调会收到这个二维码所对应的字 ...

  4. 对象输入输出流ObjectInputStream、ObjectOutputStream(对象的序列化与反序列化)

    如题 所有关联的类需要继承Serializable 接口 文件为空,直接反序列化为发生错误; 毕竟对象为null , 序列化到文件里不是空空的! 以下笔记的原文连接: https://www.cnbl ...

  5. python Thread 函数

    构造方法: Thread(group=None, target=None, name=None, args=(), kwargs={})  group: 线程组,目前还没有实现,库引用中提示必须是No ...

  6. 07. vue-router嵌套路由

    嵌套路由用法 1.嵌套路由功能分析 点击父级路由链接显示模板内容 模板内容中又有子级路由链接 点击子级路由链接显示子级模板内容 2.父路由组件模板 父级路由链接 父组件路由填充位 <p> ...

  7. python SQLAlchemy的简单配置和查询

    背景: 今天小鱼从0开始配置了下 SQLAlchemy 的连接方式,并查询到了结果,记录下来 需要操作四个地方 1. config  ------数据库地址 2.init ----- 数据库初始化 3 ...

  8. CollectionUtils.select用法

    import java.util.ArrayList;import java.util.List; import org.apache.commons.collections.CollectionUt ...

  9. 洛谷 P3958 奶酪 题解

    思路: 先看哪两个点能互通,再广搜寻找下一步,如果到达高度h就输出Yes,如果所有路径都找过都不能到达高度h就输出No. #include<bits/stdc++.h> using nam ...

  10. HAVING 搜索条件在进行分组操作之后应用

    HAVING 搜索条件在进行分组操作之后应用: 如:查询帖子访问量大于15的用户id: select t.user_id,u.name,sum(count_view) from t_topic t l ...