文章大部分来源于:http://www.cnblogs.com/zhaoyl/archive/2012/07/07/2580749.html 作为笔记留存博客备忘。

exec和source都属于bash内部命令(builtins commands),在bash下输入man exec或man source可以查看所有的内部命令信息。

bash shell的命令分为两类:外部命令和内部命令。外部命令是通过系统调用或独立的程序实现的,如sed、awk等等。内部命令是由特殊的文件格式(.def)所实现,如cd、history、exec等等。

在说明exe和source的区别之前,先说明一下fork的概念以及常见的shell script执行方式。

  fork是linux的系统调用,用来创建子进程(child process)。子进程是父进程(parent process)的一个副本,从父进程那里获得一定的资源分配以及继承父进程的环境。子进程与父进程唯一不同的地方在于pid(process id)。

环境变量(传给子进程的变量,遗传性是本地变量和环境变量的根本区别)只能单向从父进程传给子进程。不管子进程的环境变量如何变化,都不会影响父进程的环境变量。

shell script 常见的执行方式有两种,一种是新产生一个shell,然后执行相应的shell scripts;一种是在当前shell下执行,不再启用其他shell。

1. 新产生一个shell然后再执行scripts的方法是在scripts文件开头加入以下语句

#!/bin/sh

一般的script文件(.sh)即是这种用法。这种方法先启用新的sub-shell(新的子进程),然后在其下执行命令。

2. 另外一种方法就是上面说过的source命令,不再产生新的shell,而在当前shell下执行一切命令。

可以做个测试,我们有一个简单的脚本叫output.sh

第一行输出执行该脚本的shell进程ID

第二行输出其父进程ID

我们启动系统的shell窗口并查看该shell的进程ID和父进程ID:

执行output.sh

其进程ID不同于之前的shell进程ID,且父进程ID为之前的shell 进程ID,说明这种执行方式是新产生一个shell,然后执行相应的shell scripts;

再看以source方式执行:

无论是进程ID还是父进程ID都和之前的shell一模一样,说明source命令在当前shell下执行,不再启用其他shell。

下面提提exec,exec命令在执行时会把当前的shell process关闭,然后换到后面的命令继续执行。

1. 系统调用exec是以新的进程去代替原来的进程,但进程的PID保持不变。因此,可以这样认为,exec系统调用并没有创建新的进程,只是替换了原来进程上下文的内容。原进程的代码段,数据段,堆栈段被新的进程所代替。

一个进程主要包括以下几个方面的内容:

(1)一个可以执行的程序

(2) 与进程相关联的全部数据(包括变量,内存,缓冲区)

(3)程序上下文(程序计数器PC,保存程序执行的位置)

2. exec是一个函数簇,由6个函数组成,分别是以excl和execv打头的。

执行exec系统调用,一般都是这样,用fork()函数新建立一个进程,然后让进程去执行exec调用。我们知道,在fork()建立新进程之后,父进各与子进程共享代码段,但数据空间是分开的,但父进程会把自己数据空间的内容copy到子进程中去,还有上下文也会copy到子进程中去。而为了提高效率,采用一种写时copy的策略,即创建子进程的时候,并不copy父进程的地址空间,父子进程拥有共同的地址空间,只有当子进程需要写入数据时(如向缓冲区写入数据),这时候会复制地址空间,复制缓冲区到子进程中去。从而父子进程拥有独立的地址空间。而对于fork()之后执行exec时,这种策略能够很好的提高效率,如果一开始就copy,那么exec之后,子进程的数据会被放弃,被新的进程所代替。

3. exec与system的区别

(1) exec是直接用新的进程去代替原来的程序运行,运行完毕之后不回到原先的程序中去。

(2) system是调用shell执行你的命令,system=fork+exec+waitpid,执行完毕之后,回到原先的程序中去。继续执行下面的部分。

总之,如果你用exec调用,首先应该fork一个新的进程,然后exec. 而system不需要你fork新进程,已经封装好了。

shell 中 exec 和 source 命令解析的更多相关文章

  1. shell 中exec、source以及bash的区别

    在bash shell中,source.exec以及sh都可以用来执行shell script,但是它们的差别在哪里呢? sh:父进程会fork一个子进程,shell script在子进程中执行 so ...

  2. shell中的内建命令, 函数和外部命令

    转自shell中的内建命令, 函数和外部命令 Shell识别三种基本命令:内建命令.Shell函数以及外部命令: (1)内建命令就是由Shell本身所执行的命令.    有些命令是由于其必要性才内建的 ...

  3. 【转】shell中的内建命令, 函数和外部命令

    原文:http://www.cnblogs.com/xkfz007/archive/2011/10/13/2209571.html linux命令有内部命令和外部命令之分.内部命令实际上是shell程 ...

  4. shell 中如何判断前一个命令是否执行成功

    shell 中如何判断前一个命令是否执行成功 通过判断返回值来解决: if [ $? -eq 0 ];then 命令正确的分支 else   命令失败的分支 fi

  5. adb shell中的am pm命令

    adb shell中的am pm命令,一些自己的见解和大多数官网的翻译. am命令 am全称activity manager,你能使用am去模拟各种系统的行为,例如去启动一个activity,强制停止 ...

  6. shell中exec解析(转)

    参考:<linux命令.编辑器与shell编程> <unix环境高级编程> exec和source都属于bash内部命令(builtins commands),在bash下输入 ...

  7. shell中exec解析

    参考:<linux命令.编辑器与shell编程> <unix环境高级编程> exec和source都属于bash内部命令(builtins commands),在bash下输入 ...

  8. shell中exec命令

    1.find中的-exec参数 在当前目录下(包含子目录),查找所有txt文件并找出含有字符串"bin"的行 find ./ -name "*.txt" -ex ...

  9. [100]shell中exec解析

    参考:<linux命令.编辑器与shell编程> <unix环境高级编程> 本地变量可以理解为局部变量,参考:shell基础 参考 bash shell的命令分为两类:外部命令 ...

随机推荐

  1. Atitit.跨语言系统服务管理器api兼容设计

    Atitit.跨语言系统服务管理器api兼容设计 1. Common api,兼容sc ,service control??1 1.1. 服务创建,use sc1 1.2. 服务delete ,use ...

  2. 【问题记录】mysql设置任意ip访问

    # 给username用户授予可以用任意IP带密码password访问数据库 GRANT ALL PRIVILEGES ON *.* TO 'username'@'%'IDENTIFIED BY 'p ...

  3. 【ubantu】在Ubuntu上安装tar.gz,tar.bz以及deb文件(例:libreoffice安装)

    参考文章: https://blog.csdn.net/zhuquan945/article/details/52986712 ==================================== ...

  4. Mysql CAST()函数

      (1).CAST()函数的参数是一个表达式,它包括用AS关键字分隔的源值和目标数据类型.以下例子用于将文本字符串'12'转换为整型: SELECT CAST('12' AS int) (2).返回 ...

  5. Java研发工程师面试题

    基础题 一.String,StringBuffer, StringBuilder 的区别是什么?String为什么是不可变的?1. String是字符串常量,StringBuffer和StringBu ...

  6. 在ListView的GroupItem头中显示每列的Summary

    问题描述 WPF自带的ListView和DataGrid控,都提供了数据分组的支持,并可以对分组的Header进行自定义.但是,如果想在每个分组的Header中,显示出本分组的"小计&quo ...

  7. python字符串基本方法

    字符串类型在Python中是十分重要的类型,他一般用引号中间添加字符的形式表达,不同于其他语言的是,Python中双引号(” “)与单引号(’ ‘)是不予区分的.都可以用来表示字符串 创建.赋值和访问 ...

  8. nginx中使用waf防火墙

    1.安装依赖 yum install -y readline-devel ncurses-devel 2.安装Lua # .tar.gz # cd lua- # make linux # make i ...

  9. struts自定义拦截器实现

    示例 添加新功能:只有是登录的状态访问hello_loginSuccess才会显示登录成功. index.jsp登录成功页面 test.jsp登录页面 一.修改原代码实现 1.登录后将登录信息添加到S ...

  10. Swift来了,是不是能够入手IOS开发了?

    在今天的WWDC2014上,苹果公布了一种全新的Swift.在苹果高管 Craig Federighi 的描写叙述中,Swift 在各个方面优于 Objective-C,也不会有那么多复杂的符号和表达 ...