LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 2957|回复: 4

程序中能否直接用dup实现重定向?

[复制链接]
发表于 2003-3-1 11:57:49 | 显示全部楼层 |阅读模式
能否直接将STDOUT_FILENO或STDIN_FILENO直接复制给所要重定向到的文件???
发表于 2003-3-1 19:18:24 | 显示全部楼层
看来对linux/unix环境编程了解的人还是太少,我来回答你的问题吧。
dup的作用就是打开一个新的文件描述符。这个新的文件描述符与作为它参数的那个现有文件描述符指向的是同一个文件。dup创建的新文件描述符永远取最小的可用值。因此,如果先关闭文件描述符“0”,再调用dup,这样得到的新文件描述符就是“0”。这个取值“0”的新文件描述符就是一个现有文件描述符的复制品,所以标准输入就会改为指向一个文件或者管道。
下面这段程序把文件描述符重这向到管道:

  1. #include <unistd.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <string.h>

  5. int main()
  6. {
  7.     int data_processed;
  8.     int file_pipes[2];
  9.     const char some_data[] = "123";
  10.     pid_t fork_result;

  11.     if (pipe(file_pipes) == 0) {
  12.         fork_result = fork();
  13.         if (fork_result == (pid_t)-1) {
  14.             fprintf(stderr, "Fork failure");
  15.             exit(EXIT_FAILURE);
  16.         }

  17.         if (fork_result == (pid_t)0) {
  18.             close(0);
  19.             dup(file_pipes[0]);
  20.             close(file_pipes[0]);
  21.             close(file_pipes[1]);

  22.             execlp("od", "od", "-c", (char *)0);
  23.             exit(EXIT_FAILURE);
  24.         }
  25.         else {
  26.             close(file_pipes[0]);
  27.             data_processed = write(file_pipes[1], some_data,
  28.                                    strlen(some_data));
  29.             close(file_pipes[1]);
  30.             printf("%d - wrote %d bytes\n", (int)getpid(), data_processed);
  31.         }
  32.     }
  33.     exit(EXIT_SUCCESS);
  34. }
复制代码
发表于 2003-3-2 05:31:04 | 显示全部楼层
用dup2.
"能否直接将STDOUT_FILENO或STDIN_FILENO直接复制给所要重定向到的文件???"
重定向应该是反过来,把打开的文件的描述符复制给STDxx_FILENO.
发表于 2003-3-2 08:04:56 | 显示全部楼层
对,用dup2更符合原意。
发表于 2004-11-29 11:45:09 | 显示全部楼层
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <sys/types.h>

  5. void extract(char *src,char *dest1,char *dest2)
  6. {
  7. while( *src != ' ' )
  8.   *(dest1++) = *(src++);
  9. *dest1 = '\0';
  10. src++;
  11. while( *src != '\0')
  12.   *(dest2++) = *(src++);
  13. *dest2 = '\0';   
  14. }

  15. int main(int argc,char *argv[])
  16. {
  17. pid_t pid;
  18. int fd[2];
  19. pipe(fd);
  20. pid=fork();
  21. if(pid < 0)
  22.   printf("Can not fork!");
  23. else if(pid > 0)
  24. {
  25.   printf("In parent process.\n");
  26.   char exec[10],param[100];
  27.   extract(argv[1],exec,param);
  28.   if(fd[1] != STDOUT_FILENO)
  29.   if(dup2(fd[1],STDOUT_FILENO)==-1)
  30.    printf("Dup failed!\n");
  31.   close(fd[0]);
  32.   execlp(exec,exec,param);
  33.   wait(NULL);
  34. }
  35. else
  36. {
  37.   printf("In child process.\n");
  38.   char exec[10],param[100];
  39.   extract(argv[2],exec,param);
  40.   if(fd[0] != STDIN_FILENO)
  41.    dup2(fd[0],STDIN_FILENO);
  42.   close(fd[1]);
  43.   execlp(exec,exec,param);
  44. }
  45. }
复制代码


程序运行例子:
[root@Trainer ~]# ./pipe "cat /etc/passwd" "grep root"
In parent process.
In child process.
root:x:0:0:root:/root:/bin/bash
operator:x:11:0perator:/root:/sbin/nologin
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表