Bourne shell的IO重定向语法2>&1,意在通知shell把标准错误(文件描述符2)重定向到标准输出(文件描述符1)。因此下列命令将把标准输出和标准错误写入result.log文件。(shell按从左至右的顺序处理IO重定向语句)

shell通过复制文件描述符2实现了标准错误的重定向操作,因此文件描述2与文件描述符1指向同一个打开文件的句柄。可以通过调用dup和dup2来实现此功能。

对于这种重定向的操作,仅仅打开一个目标文件两次是远远不够的(第一次在描述符1上打开,第二次在描述符2上打开)。

首先两个文件不能共享文件偏移量指针,因此有可能导致相互覆盖彼此的输出。

再者打开的文件不一定就是磁盘文件。

在如下命令中,标准错误就将和标准输出一起送达同一管道。

$ ./myscript 2>&1 | less

2>1的作用是把标准错误的输出重定向到1,但这个1不是标准输出,而是一个文件,文件名就是1。

2>&1的作用是把标准错误的输出重定向到标准输出1,&指示不要把1当作普通文件,而是fd=1即标准输出来处理。

dup调用复制一个打开的文件描述符oldfd,并返回一个新的描述符,二者都指向同一打开的文件句柄。系统会保证新文件描述符一定是编号值最低的未使用文件描述符。

int dup(int oldfd);

加入发起如下调用:

newfd = dup(1);

在假定在正常的情况下,shell已经代表程序打开了文件描述符0、1和2,且没有其他描述符在用,dup调用会创建文件描述符1的副本,返回的文件描述符编号值为3。

如果希望返回的文件描述符为2,可以这样:

close(2);
newfd = dup(1);

只有当描述符0已经打开的时候,这段代码方可工作。而且这样做也是有问题的,因为这并不是一个原子操作。如果想进一步简化如下的代码,同时希望获得所期望的文件描述符,可以调用dup2。

int dup2(int oldfd, int newfd);

dup2系统调用会为oldfd参数所指定的文件描述符创建副本,其编号由newfd参数指定。如果由newfd参数所指定的编号的文件描述符之前已经打开了,那么dup2会首先将其关闭。

dup2调用会默认忽略newfd关闭期间出现的任何错误。故此,编码时更为安全的做法是:在调用dup2之前,如果newfd已经打开,则应显式调用close将其关闭。(那要是我不知道newfd是否打开了怎么判断呢?)

之前调用dup和close可以简化为:

dup(1, 2);

如果dup2调用成功,则将返回副本的文件描述符编号(即newfd参数指定的值)。

如果oldfd并非有效的文件描述符,那么dup2调用将失败并返回错误EBADF,且不关闭newfd。如果oldfd有效,且与newfd的值相等,那么dup2将什么也不做,不关闭newfd,并将其作为调用结果返回。

fcntl的F_DUPFD操作是复制文件描述符的另一接口,更具有灵活性。

newfd = fcntl(oldfd, F_DUPFD, startfd);

该调用为oldfd创建一个副本,且将使用大于等于startfd的最小未使用值作为描述符编号。该调用还能保证新描述符newfd编号落在特定的区间范围内。总是能将dup和dup2的调用改写为对close和fcntl的调用。

文件描述符的正、副本之间共享打开文件句柄所含的文件偏移量和状态标志。然后新文件描述符有其自己的一套文件描述符标志,且其close-on-exec标志(FD_CLOEXEC)总处于关闭状态。

下面的接口可以直接控制新文件描述符的close-on-exec标志。

dup3系统调用完成的工作与dup2相同,只是新增了一个附加参数flag,这一个可以是修改系统调用行为的位掩码。

int dup3(int oldfd, int newfd, int flags);

目前dup3只支持一个标志O_CLOEXEC。

dup3只在Linux 2.6.27以后才有,是Linux特有的。

Linux从2.6.24开始支持fcntl用于复制文件描述符的附加命令:F_DUPFD_CLOEXEC。

该标志不仅实现了与F_DUPFD相同的功能,还为新文件描述符设置close-on-exec标志。

这一节有好多系统系统调用:dup,dup2,dup3,fcntl

Unix系统编程()复制文件描述符的更多相关文章

  1. dup等复制文件描述符函数

    [root@bogon code]# cat b.c #include<stdio.h> #include<error.h> #include<unistd.h> ...

  2. 复制文件描述符---dup

    函数功能:复制文件描述符 头文件:#include<unistd.h> 函数原型:int dup(int oldfd) 参数说明:oldfd:旧的文件描述符 返回值:成功返回-个新的文件描 ...

  3. fcntl函数用法——复制文件描述符

    文件描述符复制和输出重定向dup() 用最小的文件描述符来复制,从0开始搜素.复制文件描述符后,最小文件描述符指向被复制描述符指向的文件.dup2(int oldfd,int newfd) 强制用ne ...

  4. UNIX环境编程学习笔记(4)——文件I/O之dup复制文件描述符

    lienhua342014-08-23 UNIX 提供了两个函数 dup 和 dup2 用于复制一个现存的文件描述符. #include <unistd.h> int dup(int fi ...

  5. UNIX系统编程:文件IO(I)

    1.标准C库中访问文件用的是文件指针FILE *(stdin,stdout,stderr):对于linux系统编程而言,所有对设备或文件的操作都是通过文件描述符进行的 2.当打开或者创建一个文件的时候 ...

  6. Linux系统编程--文件描述符的复制dup()和dup2()【转】

    本文转载自:http://blog.csdn.net/tennysonsky/article/details/45870459 dup() 和 dup2() 是两个非常有用的系统调用,都是用来复制一个 ...

  7. linux系统编程之文件与IO(八):文件描述符相关操作-dup,dup2,fcntl

    本节目标: 1,文件共享 打开文件内核数据结构 一个进程两次打开同一个文件 两个进程打开同一个文件 2,复制文件描述符(dup.dup2.fcntl) 一,文件共享 1,一个进程打开两个文件内核数据结 ...

  8. Unix系统编程()深入探究文件IO概述

    open调用将引入原子atomicity操作的概念. 将某一系统调用所要完成的各个动作作为不可中断的操作,一次性加以执行. 原子操作是许多系统调用得以正确执行的必要条件. 还介绍一个系统调用fcntl ...

  9. 《Linux/Unix系统编程手册》读书笔记2

    <Linux/Unix系统编程手册>读书笔记 目录 第5章: 主要介绍了文件I/O更深入的一些内容. 原子操作,将一个系统调用所要完成的所有动作作为一个不可中断的操作,一次性执行:这样可以 ...

随机推荐

  1. FrameWork数据权限浅析3之基于角色的配置表实现行级数据安全

    带着上一次笔记的疑问和些许欢喜来到了混混沌沌的下午,程序员的脑子一直在不停的思索着,而多思考总是没错的,盼望着盼望着事情就有了转机,现在我们就来说一说基于角色级别的中间表机制实现行级数据安全. 由于本 ...

  2. boost::asio 之udp协议的使用

    write by http://blog.csdn.net/bojie5744 bj_末雨 udp sender #include "stdafx.h" #include < ...

  3. ejs和swig对比问题之二

    上一次用浏览器里面简单的进行了测试,得到的数据是swig是ejs的速度的一倍左右,这次在控制台进行测试,能够得到比较精确的数据,并加入了dot一块儿进行测试. 测试数据是一百万条记录 创建测试数据cr ...

  4. ASP.NET HTTP404错误怎么办

    如图所示,HTTP404错误. 这是由于没有安装ASP.NET导致的.我们在控制面板->打开或关闭windows功能->Internet信息服务->万维网服务->应用程序开发功 ...

  5. 用thinkphp连接mysql数据库

    一.设置mysql数据库的参数 thinkphp\Application\Home\Conf\config.php <?php return array( //'配置项'=>'配置值' ' ...

  6. 通过micrometer实时监控线程池的各项指标

    通过micrometer实时监控线程池的各项指标 前提 最近的一个项目中涉及到文件上传和下载,使用到JUC的线程池ThreadPoolExecutor,在生产环境中出现了某些时刻线程池满负载运作,由于 ...

  7. UG NX9.0.0 for linux安装

    自:http://vivianyw.blog.163.com/blog/static/13454742220145601415881/?latestBlog NX9.0.0 for linux安装. ...

  8. 安装SQL SERVER 2016 CTP (二)[多图]

    内容中包含 base64string 图片造成字符过多,拒绝显示

  9. bootstrap model弹出框的使用

    之前,我们讲解了bootstrap tab的使用,今天我们来了解下bootstrap 中model弹出窗的使用. 效果: 代码:<input id="btntext" typ ...

  10. llinux环境变量查看和修改

    查看全局环境变量:env 查看所有环境变量:set 删除一个变量:unset [变量名] #只针对当前会话 设置一个变量:name=songjiankang export name #将这个变量提升为 ...