实际的例子使用dup或dup2

我知道dupdup2做什么,但我不知道什么时候可以使用。 任何实际的例子? 谢谢。

一个示例使用将是I / Oredirect。 为此,你分叉一个subprocess并closuresstdin或者stdout文件描述符(0和1),然后在你select的另一个文件描述符上做一个dup(),这个文件描述符现在将被映射到最低的可用文件描述符,情况0或1。

使用这个,你现在可以执行任何可能不了解你的应用程序的subprocess,并且每当孩子在标准输出上写入(或者从标准input读取,不pipe你configuration了什么),数据都被写在提供的文件描述符上。

炮弹使用这个来实现pipe道的突击队,例如/bin/ls | more /bin/ls | more通过将一个进程的标准输出连接到另一个进程的标准input。

理解dup和dup2的最佳场景是redirect。
首先我们需要知道的是,系统有3个默认的文件ID(或指示输出或input源的variables)处理input和输出。 他们是stdinstdoutstderr ,整数是0 。 大多数函数,如fprintfcout都直接输出到stdout
如果我们要redirect输出,一种方法是给,例如, fprintf函数更多的参数指示out
不过,有一个更优雅的方法:我们可以覆盖默认的文件ID,使它们指向我们想要接收输出的文件。 dupdup2恰好在这种情况下工作。
现在我们来看一个简单的例子:假设我们想把fprintf的输出redirect到一个名为“chinaisbetter.txt”的txt文件。 首先我们需要打开这个文件

 int fw=open("chinaisbetter.txt", O_APPEND|O_WRONLY); 

然后我们希望stdout使用dup函数指向“chinaisbetter.txt”:

 dup2(fw,1); 

现在stdout(1)指向“chinaisbetter.txt”的描述符,即使它仍然是1,但是输出现在被redirect了。
然后你可以printf使用printf ,但结果将会在txt文件中,而不是直接显示在屏幕上:

 printf("Are you kidding me? \n"); 

PS

  1. 这只是给出了一个直观的解释,您可能需要检查联机帮助或详细信息。 其实我们在这里说“复制”,他们并不是抄袭一切。

  2. 这里的文件ID是指文件的处理程序。 上面提到的文件描述符是logging文件信息的结构。

当你对POSIX函数感到好奇的时候,尤其是那些似乎自己复制的函数,通常是很好的检查标准本身 。 在底部,你通常会看到一些例子,以及两者的实现(和存在)背后的推理。

在这种情况下:

以下部分是资料性的。

例子

将标准输出redirect到文件

以下示例closures当前进程的标准输出,重新分配标准输出以转到由pfd引用的文件,并closures原始文件描述符以进行清理。

 #include <unistd.h> ... int pfd; ... close(1); dup(pfd); close(pfd); ... 

redirect错误消息

以下示例将邮件从stderrredirect到stdout

 #include <unistd.h> ... dup2(2, 1); // 2-stderr; 1-stdout ... 

应用程序使用

没有。

合理

dup()dup2()函数是多余的。 他们的服务也由fcntl()函数提供。 由于许多现有的应用程序使用它们,主要出于历史原因,它们已经被包括在IEEE Std 1003.1-2001的这一卷中。

尽pipe所显示的简短代码段在行为上与dup2()非常相似,但基于IEEE Std 1003.1-2001本卷中定义的其他函数的一致性实现要复杂得多。 最明显的是信号捕捉function的可能影响,可以在步骤之间调用,并分配或释放文件描述符。 这可以通过阻止信号来避免。

dup2()函数没有被标记为过时的,因为它提供了fcntl()在types不安全的版本中提供的function的types安全版本。 它用于POSIX Ada绑定。

dup2()函数不适合在关键区域用作同步机制。

在[EBADF]的描述中,fildes超出范围的情况由给定的fildes无效的情况所涵盖。 fildesfildes2的描述是不同的,因为与fildes2相关的唯一一种无效性是否超出范围; 也就是说,在进行dup2()调用时, fildes2是否指向一个打开的文件并不重要。

未来发展方向

没有。

也可以看看

close()fcntl()open() ,IEEE Std 1003.1-2001的基本定义卷, <unistd.h>

更改历史logging

首先在问题1中发布。源自SVID的问题1。

一个实际的例子是将输出消息redirect到某些其他stream,如某些日志文件。 以下是I / Oredirect的示例代码。
请在这里参考原文

 #include <stdio.h> main() { int fd; fpos_t pos; printf("stdout, "); fflush(stdout); fgetpos(stdout, &pos); fd = dup(fileno(stdout)); freopen("stdout.out", "w", stdout); f(); fflush(stdout); dup2(fd, fileno(stdout)); close(fd); clearerr(stdout); fsetpos(stdout, &pos); /* for C9X */ printf("stdout again\n"); } f() { printf("stdout in f()"); }