基本概念(具體參見APUE):
一個進程控制塊中有多個文件描述符(file descriptor),如:
fd0:標準輸入
fd1:標準輸出
fd2:標準輸錯
fd3:自定義
fd4:自定義
...
每個文件描述符對應一個指向file table的指針。
重定向使用dup()/dup2()系統調用,
dup()的原型爲:
int dup(int filedes)
函數返回當前可用的最小文件描述符,此描述符的file pointer與filedes的file pointer指向相同的file table。dup2()的原型爲:
int dup(int filedes, int filedes2)
函數指定filedes2與filedes的file pointer指向相同的file table。下面是一個使用dup()的實例代碼,功能爲使進程的文件描述符1(標準輸出)與文件"file1"的文件描述符的file pointer指向同一個file table,即將進程的標準輸出寫入到文件"file1"中,也就是shell中常用的重定向'>'操作。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
int main()
{
int fd;
if ((fd = open("file1", O_RDWR | O_CREAT | O_TRUNC, 00664)) < 0) {
perror("open");
exit(EXIT_FAILURE);
}
close(STDOUT_FILENO);
dup2(fd, STDOUT_FILENO);
char *buf = "I wrote this string to stdout.\n";
if (write(STDOUT_FILENO, buf, strlen(buf)) != strlen(buf)) {
perror("write");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
總結:這兩個函數的功能是使兩個文件描述符的file pointer指向同一個file table,從而可以共享打開的文件。管道使用pipe()系統調用,
原型爲:
int pipe(pipefd[2])
其中:pipefd[0]爲管道的read端
pipefd[1]爲管道的write端
下面是man 2 pipe的一個實例代碼,功能爲父進程向管道的write端寫入argv[1],子進程從管道的read端逐個字符讀入buf,然後輸出到標準輸出。
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char *argv[])
{
int pipefd[2];
pid_t cpid;
char buf;
if (argc != 2) {
fprintf(stderr, "Usage: %s <string>\n", argv[0]);
exit(EXIT_FAILURE);
}
if (pipe(pipefd) == -1) { /× create a pipe */
perror("pipe");
exit(EXIT_FAILURE);
}
if ((cpid = fork()) < 0) {
perror("fork");
exit(EXIT_FAILURE);
}
else if (cpid == 0) { /* child process */
close(pipefd[1]); /* close write end of pipe */
while (read(pipefd[0], &buf, 1) == 1) /* read from read end of pipe */
write(STDOUT_FILENO, &buf, 1); /* write buf to STDOUT */
write(STDOUT_FILENO, "\n", 1);
close(pipefd[0]);
_exit(EXIT_SUCCESS);
}
else { /* parent process */
close(pipefd[0]); /* close read end of pipe */
write(pipefd[1], argv[1], strlen(argv[1])); /* write argv[1] to write end of pipe */
close(pipefd[1]);
wait(NULL);
exit(EXIT_SUCCESS);
}
}
區別:重定向(redirect)主要是對同一個進程而言的,而管道(pipe)可用於進程間通信(IPC)。