看到好几篇文章讲述exec都是一知半解,所以我尽量说的清楚明白一些。本文首先讲述Linux文件描述符,然后是exec,最后举例说明exec I/O重定向及其用法。

概念:exec命令用于调用并执行指令的命令。exec命令通常用在shell脚本程序中,可以调用其他的命令。如果在当前终端中使用命令,则当指定的命令执行完毕后会立即退出终端。
语法:
exec(选项)(参数)
选项:
-c:在空环境中执行指定的命令。
参数:
指令:要执行的指令和相应的参数。
实例:
首先使用echo命令将文本“Linux C++”进行输出,输入如下命令:
echo Linux C++ #输出指定信息
执行上面的指令后,输出如下信息:
Linux C++ #输出信息
然后再使用exec命令调用echo命令输出同样的信息,并且对输出的信息进行对比,输入指令如下所示:
exec -c echo Linux C++ #调用命令
执行以上命令后,其输出信息如下(并退出当前终端):
Linux C++ #使用指定指令输出信息 通过比较两者执行后的结果来看,所实现的功能是相同的,即使用exec命令调用echo命令成功。

1 Linux文件描述符介绍

在Linux系统中一切皆可以看成是文件,文件又可分为:普通文件、目录文件、链接文件和设备文件。文件描述符(file descriptor简称FD)是内核为了高效管理已被打开的文件所创建的索引,其是一个非负整数(通常是小整数),用于指代被打开的文件,所有执行I/O操作的系统调用都通过文件描述符。最前面的三个文件描述符(0,1,2)分别与标准输入(stdin),标准输出(stdout)和标准错误(stderr)对应。因此,函数 scanf() 使用 stdin,而函数 printf() 使用 stdout。你可以用不同的文件描述符改写默认的设置并重定向进程的 I/O 到不同的文件。Unix 操作系统通常给每个进程能打开的文件数量强加一个限制。

例如:要把标准输出(1)和标准错误(2)重定向到一个文件,使用如下命令

xx命令 >& filename

查看LINUX默认的文件描述符数:

# ulimit -n

使用用如下命令来增大文件描述符数:

ulimit -HSn 

2 exec原理介绍

exec和source都属于bash内部命令(builtins commands),
    source:

source命令即点(.)命令。

在bash下输入man source,找到source命令解释处,可以看到解释”Read and execute commands from filename in thecurrent shell environment and …”。从中可以知道,source命令是在当前进程中执行参数文件中的各个命令,而不是另起子进程(或sub-shell)。

exec:

在bash下输入man exec,找到exec命令解释处,可以看到有”No new process is created.”这样的解释,这就是说exec命令不产生新的子进程。那么exec与source的区别是什么呢? exec命令在执行时会把当前的shell process关闭,然后换到后面的命令继续执行。

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

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

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

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

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

描述exec命令最贴切的说法是:它践踏了你当前的shell。

当这个脚本结束了,相应的会话可能也就结束了。

但是,exec在对文件描述符进行操作的时候(也只有在这个时候),它不会覆盖你当前的shell。

3 exec I/O重定向基本概念和应用案例

3.1 基本概念(可以大体看一下意思,等看到后面的例子再来参考)

1 常用FD(文件描述符)有3个,为0(stdin,标准输入)、1(stdout,标准输出)、2(stderr,标准错误输出),但你也可以指定其他数字作为文件描述符;

2 bash(ksh)执行命令的过程:分析命令-变量求值-命令替代(``和$( ))-重定向-通配符展开-确定路径-执行命令;

exec用法总结

exec命令

作用

exec ls

在shell中执行ls,ls结束后不返回原来的shell中了

exec <file

将file中的内容作为exec的标准输入

exec >file

将file中的内容作为标准写出

exec 3<file

将file读入到fd3中

exec 3>file

将写入fd3中的内容写入file中

sort <&3

fd3中读入的内容被分类

ls >&4

Ls将不会有显示,直接写入fd4中了,即上面的file中,此处ls也可以替换为任何命令

exec 5<&4

创建fd4的拷贝fd5

exec 3<&-

关闭fd3

1、通过exec分配文件描述符3.2 应用案例
#!/bin/sh
exec <>hello.txt           # 以读写方式绑定到文件描述符"
       # 写入"hello exec",如果之前有内容,这里将会从文件开头进行覆盖
      # 写入"hello world“,新的一行!
exec >&-                   # 关闭写,禁止写,然而,实际上它也不能读了~
                            # 如果是exec <&-,关闭读,同时它也不能写了~

打开文件,看到的结果如下

[root@vmtest01 tmp]# cat hello.txt
hello exec                                 #首次插入的在第一行
hello world        #第二次在新的一行
errfilename        #下面的都是旧数据,依旧保留
hello.txt
systemd-private-CEGg3c
test

2、将标准输出重定向到hello.txt

#!/bin/sh
exec >hello.txt        # 将标准输出重定向到文件hello.txt,从此以后,当前环境(shell)中的的标准输出都将被写入文件hello.txt
echo "hello exec"
echo "hello world"

这样,在终端再也见不着标准输出了,因为所有标准输出到放大文件hello.txt中了
如果你现在运行who am i命令,终端什么都不显示,打开另外一个终端

可以发现hello.txt文件的内容如下

[root@vmtest01 tmp]# cat hello.txt
hello exec
hello world
root     pts/        -- : (192.168.233.1)  #这是who am i命令的输出,已经重定向到该文件中了

3、在上面这个示例中,标准输出被重定向了,如果要恢复怎么办?

#!/bin/sh
exec >&             # 将文件描述符100连接到标准输出,此时100 和1同时指向hello.txt,即echo  和echo "hello exec"的效果一样,都写入hello.txt
                        # 由于之后还要输出到终端,所以我们不得不使用一个临时的描述符来保存它!
exec >hello.txt        # 首先清空hello.txt,并再次将标准输出重定向到文件hello.txt,从此以后,这个环境中的标准输出都将被写入文件hello.txt
echo "hello exec"
exec >& >&-      # 将标准输出连接到100,这是之前保存的标准输出
                        # 将描述符100关了,一了百了,因为已经还原标准输出了,留着它实在没必要
echo "oh, my god!"      # 从这句开始将显示在终端上

4、标准输入的操作与2、3相似,只是使用的是"<"

注意,下面这个必须存到脚本里面执行,不然总是会退出登录

#!/bin/sh
exec <&
exec <hello.txt      #假设hello.txt只有一行
read line1
echo $line1
exec <& >&-     # 将标准输入连接到100
                        # 将描述符100关了,一了百了,因为已经还原标准输入了,留着它实在没必要
read -p "please input:"    custome    #测试不是文件的标准输入
echo "your input is :$custome"

参考

linux shell的一些技巧(五)exec与文件描述符

Linux中exec命令相关

linux exec和文件描述符妙用技巧

man exec命令

linux exec用法总结 比较好的讲解

Linux exec与文件描述符的更多相关文章

  1. linux exec和文件描述符妙用技巧(转)

    最近在看<精通unix shell脚本编程>时,看到exec<$1 exec 1>$OUTFILE,一下看的我就蒙了.网上看了大半天,终于搞定,记录如下.对于 Linux 而言 ...

  2. linux exec操作文件描述符

    linux每一个打开文件都会关联一个文件描述符,需要的时候我们可以使用exec命令指定一个大于3的数字作为文件 linux默认文件描述符 每打开一个shell就会打开默认的三个文件描述符描0,1,2, ...

  3. Linux中的文件描述符与打开文件之间的关系

    Linux中的文件描述符与打开文件之间的关系 导读 内核(kernel)利用文件描述符(file descriptor)来访问文件.文件描述符是非负整数.打开现存文件或新建文件时,内核会返回一个文件描 ...

  4. Linux Linux下最大文件描述符设置

    Linux下最大文件描述符设置 by:授客 QQ:1033553122 1.   系统可打开最大文件描述符设置 查看系统可打开最大文件描述符 # cat /proc/sys/fs/file-max 6 ...

  5. [svc]linux中的文件描述符(file descriptor)和文件

    linux中的文件描述符(file descriptor)和文件 linux为了实现一切皆文件的设计哲学,不仅将数据抽象成了文件,也将一切操作和资源抽象成了文件,比如说硬件设备,socket,磁盘,进 ...

  6. linux fcntl 对文件描述符控制

    linux fcntl 对文件描述符控制 linux fcntl 对文件描述符控制 linux fcntl 对文件描述符控制

  7. linux shell exec 关联文件描述符

    在写shell脚本时,如果多个命令的输入或输出都是同一个文件,而这个文件的路径和名字都很长,则需要书写很多次同样的路径会很浪费时间,我们可以使用exec命令来关联一个自定义的文件描述符到一个特定的文件 ...

  8. Linux中的文件描述符与打开文件之间的关系------------每天进步一点点系列

    http://blog.csdn.net/cywosp/article/details/38965239 1. 概述     在Linux系统中一切皆可以看成是文件,文件又可分为:普通文件.目录文件. ...

  9. (转)Linux中的文件描述符

    本文转自:http://blog.csdn.net/cywosp/article/details/38965239 作者:cywosp 1. 概述 在Linux系统中一切皆可以看成是文件,文件又可分为 ...

随机推荐

  1. 使用Tomcat的Reload提高开发速度(翻译)

    欢迎转载http://www.cnblogs.com/coodream2009,有翻译的不太准确的地方请大家指出,我继续修改完善. 按照Java Servlet规范第四部分推荐的,Tomcat系统的实 ...

  2. 【MySQL】计算 TPS,QPS 的方式

     在做db基准测试的时候,qps,tps 是衡量数据库性能的关键指标.本文比较了网上的两种计算方式.先来了解一下相关概念. 概念介绍: QPS:Queries Per Second         查 ...

  3. 使用筛选器特性标记方法解决webapi 跨域问题

    在我的之前随笔 解决api.WebService跨域问题 中有人问到可以用特性来解决跨域问题吗,答案是肯定的,可以的:操作如下: 首先建一个类CrossSiteAttribute:从抽象 Action ...

  4. EXP导出aud$报错EXP-00008,ORA-00904 解决

    主题:EXP导出aud$报错EXP-00008,ORA-00904 解决 环境:Oracle 11.2.0.4 问题:在自己的测试环境,导出sys用户下的aud$表报错. 1.故障现场 2.跟踪处理 ...

  5. C++拷贝构造函数(深拷贝与浅拷贝)

    转自http://blog.csdn.net/lwbeyond/article/details/6202256/ 一. 什么是拷贝构造函数 对于普通类型的对象来说,它们之间的复制是很简单的,例如:in ...

  6. 献给迷惘的Java架构工程师

    1. 工程化专题 (团队大于3个人之后,你需要去考虑团队合作,科学管理)  2. 源码分析专题 (好的程序员,一行代码一个设计就能看出来,源码分析带你品味代码,感受架构)  3.高性能及分布式专题 ( ...

  7. javascript初识

    1.什么是js 基于对象和事件驱动并且具有相对安全性的客户端脚本语言,由网景公司开发.     2.js数据类型   1.基本数据类型 undefined,null,number,boolean,st ...

  8. 谈谈Grunt,NPM,Gulp

    随着前端工程化的趋势,产生了越来越多的构建工具,而其中比较优秀的就是grunt,npm,gulp,今天我来说说这三者间的区别以及他们的优缺点. 相信一般前端开发者选择构建工具的时候,更多的是看个人习惯 ...

  9. Linux磁盘使用过载

    系统出现磁盘占用达到100%导致系统崩溃 查看那些个磁盘使用达到100% 命令 df -h  我们发现是www目录使用达到100%,开始清理,首先查找大于100M的大文件 find / -size + ...

  10. [C#]使用控制台获取天气预报

    本例子主要是使用由中央气象局网站(http://www.nmc.gov.cn)提供的JSON API,其实现思路如下: 1.访问获取省份(包含直辖市.自治区等,以下简称省份)的网址(http://ww ...