如下:

  • 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. golang静态编译

    golang 的编译(不涉及 cgo 编译的前提下)默认使用了静态编译,不依赖任何动态链接库. 这样可以任意部署到各种运行环境,不用担心依赖库的版本问题.只是体积大一点而已,存储时占用了一点磁盘,运行 ...

  2. 使用Cloudera Manager添加Sentry服务

    使用Cloudera Manager添加Sentry服务 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.通过CM添加Sentry服务 1>.点击添加服务进入CM服务安装向 ...

  3. O(n) 取得数组中每个元素右边第一个比它大的元素

    题目: 给定一个整型数组,数组元素随机无序的,要求打印出所有元素右边第一个大于该元素的值. 如数组A=[6,8,9,2,3,5,6] 输出[8,9,-1,3,5,6,-1] 思路: 我们用栈来保存未找 ...

  4. php的希尔排序

    算是改进了的插入排序, 从性能时间上来看,也确实更有改进. 但比起php内置的功能,性能还有十倍之差呢 <?php /** * 原理:把排序的数据根据增量分成几个子序列,对子序列进行插入排序, ...

  5. Hive优化(整理版)

    1. 概述 1.1 hive的特征: 可以通过SQL轻松访问数据的工具,从而实现数据仓库任务,如提取/转换/加载(ETL),报告和数据分析: 它可以使已经存储的数据结构化: 可以直接访问存储在Apac ...

  6. SparkSQL读写外部数据源--csv文件的读写

    object CSVFileTest { def main(args: Array[String]): Unit = { val spark = SparkSession .builder() .ap ...

  7. 【转】分布式事务,EventBus 解决方案:CAP【中文文档】

    [转]分布式事务,EventBus 解决方案:CAP[中文文档] 最新文档地址:https://github.com/dotnetcore/CAP/wiki 前言 很多同学想对CAP的机制以及用法等想 ...

  8. 算法笔记求序列A每个元素左边比它小的数的个数(树状数组和离散化)

    #include <iostream> #include <algorithm> #include <cstring> using namespace std ; ...

  9. 目标检测的mAp

    众多目标检测的知识中,都提到了mAp一值,那么这个东西到底是什么呢: 我们在评价一个目标检测算法的"好坏"程度的时候,往往采用的是pascal voc 2012的评价标准mAP.目 ...

  10. CentOS yum repo

    CentOS yum repo   阿里云的 一个是Centos-6的 一个是Centos-7  # CentOS 5 wget -O /etc/yum.repos.d/CentOS-Base.rep ...