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. (剑指Offer)面试题51:数组中重复的数字

    题目: 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为7 ...

  2. GTID数据库备份

    rhel6系统中,mysql 5.6复制新特性下主从复制配置[基于GTID] 1.mysql5.6在复制方面的新特性: (1).支持多线程复制:事实上是针对每个database开启相应的独立线程,即每 ...

  3. Java中字符串相等与大小比較

    在C++中,两个字符串比較的代码能够为: (string1==string2) 但在java中,这个代码即使在两个字符串全然同样的情况下也会返回false Java中必须使用string1.equal ...

  4. 《iOS用户体验》总结与思考-改动版

    假设转载此文.请注明出处:http://blog.csdn.net/paulery2012/article/details/25157347,谢谢. 前言: 本文是在阅读<ios用户体验> ...

  5. STL - vector algorithm

    // create vector with elements from 1 to 6 in arbitrary order vector<, , , , , }; // find and pri ...

  6. 很全的Python 面试题 github

    https://github.com/taizilongxu/interview_python

  7. Ubuntu 64位安装32位运行库

    sudo apt-get install ia32-libs 32-64sudo apt-get install libc6:i386sudo apt-get install librt:i386su ...

  8. 算法笔记_151:算法提高 01背包(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 问题描述 给定N个物品,每个物品有一个重量W和一个价值V.你有一个能装M重量的背包.问怎么装使得所装价值最大.每个物品只有一个. 输入格式 输入的第 ...

  9. windows合并文件夹窗口

      windows合并文件夹窗口 CreateTime--2017年7月26日16:28:14Author:Marydon 右击任务栏-->属性-->任务栏按钮选项-->选择“始终合 ...

  10. PHP-数据库长连接mysql_pconnect的细节

    PHP的MySQL持久化连接,美好的目标,却拥有糟糕的口碑,往往令人敬而远之.这到底是为啥么.近距离观察后发现,这家伙也不容易啊,要看Apache的脸色,还得听MySQL指挥. 对于作为Apache模 ...