实际的例子使用dup或dup2
我知道dup
或dup2
做什么,但我不知道什么时候可以使用。 任何实际的例子? 谢谢。
一个示例使用将是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和输出。 他们是stdin
, stdout
, stderr
,整数是0
。 大多数函数,如fprintf
或cout
都直接输出到stdout
。
如果我们要redirect输出,一种方法是给,例如, fprintf
函数更多的参数指示out
。
不过,有一个更优雅的方法:我们可以覆盖默认的文件ID,使它们指向我们想要接收输出的文件。 dup
和dup2
恰好在这种情况下工作。
现在我们来看一个简单的例子:假设我们想把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 :
-
这只是给出了一个直观的解释,您可能需要检查联机帮助或详细信息。 其实我们在这里说“复制”,他们并不是抄袭一切。
-
这里的文件ID是指文件的处理程序。 上面提到的文件描述符是logging文件信息的结构。
当你对POSIX函数感到好奇的时候,尤其是那些似乎自己复制的函数,通常是很好的检查标准本身 。 在底部,你通常会看到一些例子,以及两者的实现(和存在)背后的推理。
在这种情况下:
以下部分是资料性的。
例子
将标准输出redirect到文件
以下示例closures当前进程的标准输出,重新分配标准输出以转到由pfd
引用的文件,并closures原始文件描述符以进行清理。
#include <unistd.h> ... int pfd; ... close(1); dup(pfd); close(pfd); ...
redirect错误消息
以下示例将邮件从stderr
redirect到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无效的情况所涵盖。 fildes
和fildes2
的描述是不同的,因为与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()"); }