0%

Linux函数学习(三)—— Dup 函数

dup、dup2 函数

dupdup2 都是用来复制一个文件的描述符;常用来重定向进程的 stdinstdoutstderr

头文件

1
#include <unistd.h>

函数原型

1
2
int dup(int oldfd);
int dup2(int oldfd, int targetfd);

返回值

1
返回一个新的描述符,这个新的描述符是传给它的描述符的拷贝。

功能

  1. 都是用来复制一个文件的描述符。
  2. dup2 函数跟 dup 函数相似,但 dup2 函数允许调用者规定一个有效描述符和目标描述符的id 。dup2` 函数成功返回时,目标描述符(dup2函数的第二个参数)将变成源描述符(dup2函数的
    第一个参数)的复制品。换句话说,两个文件描述符现在都指向同一个文件,并且是函数第一
    个参数指向的文件。

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

/*
等效 bash 命令: ls -l | wc -l
v ^
| |
| |
v ^
<-------- <---------
| |
子进程 --->======管道====== |
父进程 ======管道====== --->
*/
int main()
{
int pfds[2]; // pfds[0]:读取; pfds[1]:写入
int fpid;

if (0 != pipe(pfds))
{
perror("创建管道失败:");
exit(EXIT_FAILURE);
}
fpid = fork();
if (0 == fpid) // 子进程
{
close(STDOUT_FILENO); // 关闭标准输出(终端输出)
dup2(pfds[1], STDOUT_FILENO); // 重定向标准输出(终端输出)到‘子进程’的 管道 的’写入‘端
close(pfds[0]); // 关闭’子进程‘管道的’输出端‘
execlp("ls", "ls", "-l", NULL); // 执行’ls -l‘ bash命令(其产生的结果输出到管道的’写入‘端)
}
else // 父进程
{
close(STDIN_FILENO); // 关闭标注输入(终端输入)
dup2(pfds[0], STDIN_FILENO); // 重定向标准输入(终端输入)到’父进程‘的管道的’输出‘端
close(pfds[1]); // 关闭’父进程‘管道的’写入‘端
execlp("wc", "wc", "-l", NULL); // 执行’wc -l‘ bash命令(其输入来源于管道’输出‘端)
}
return 0;
}

Demo