重定向execvp的输入/输出

时间:2017-10-09 13:51:06

标签: c system-calls

我想在程序遇到">"时将输出重定向到特定文件。并且如果它找到"<"则从文件中获取输入。

这适用于输入,但是当我尝试输出文件时,它不会在实际文件中写入任何内容,也不会在终端中显示它。

我似乎无法弄明白为什么,有人可以帮忙吗?

switch(fork()){
    case 0:

        for(i=0; i<num; i++){

            if(strcmp(argv[i], ">") == 0){
                if(fd1 = open(argv[i+1], O_RDWR | O_CREAT, S_IRUSR | S_IWUSR) < 0){
                    perror("cant open file");
                    exit(0);                    
                }
                dup2(fd1, 1);
                close(fd1);
                argv[i] = NULL;
            }

            if(strcmp(argv[i], "<") == 0){
                if(fd0 = open(argv[i+1], O_RDONLY) < 0){
                    perror("cant open file");
                    exit(0);                    
                }
                dup2(fd0, 0);
                close(fd0);
            }

        }

        execvp(argv[0], argv);

1 个答案:

答案 0 :(得分:2)

主要问题是=运算符的优先级低于<运算符。因此,在你的表达中

fd1 = open(argv[i+1], O_RDWR | O_CREAT, S_IRUSR | S_IWUSR) < 0

,将open()的返回值与0进行比较,然后将该比较的结果(1或0)分配给fd1。新打开的文件描述符丢失,并且未使用。比较的实际结果很可能是0(文件已成功打开),因此您的dup2()稍后调用几行尝试将文件描述符0转换为文件描述符1.尽可能有效,但任何尝试你执行该程序以写入该文件描述符很可能会失败。

你应该把它写成

(fd1 = open(argv[i+1], O_RDWR | O_CREAT, S_IRUSR | S_IWUSR)) < 0

或者,稍微不那么聪明并将其分成两个陈述,以便首先不会出现优先问题。

您在重定向输入时遇到同样的问题,因此我怀疑您的声明&#34;这适用于输入&#34;,但因为在这种情况下您最终只会将文件描述符0复制到自身上,问题就会表现为重定向不能按预期工作 - 输入仍然来自原始程序的标准输入,而不是您指定的标准输入。

但是,如果允许shell执行输入重定向而不是引用重定向运算符以便将其作为参数传递给程序,那么即使这可能也不会引起注意。