将输出重定向到文件会在C

时间:2016-03-25 21:35:41

标签: c shell redirect

我正在实现一个shell并且正在进行重定向:将输出写入文件或从文件读取输入。我面临的问题是:

  • 我得到的文件的名称是" `b "如果我输入此命令作为我的程序的输入" sort<的test.txt "虽然它不应该写入文件!和程序挂起,没有排序输出!

  • 如果我输入:" ls> out.txt ",输出被写入终端和 out.txt 文件

  • 该程序应该永远接受输入,直到用户写出"退出"但是,在关闭程序之后,在输入任何需要重定向的命令后,程序会停止,因此它只会执行一次带有重定向的cmd然后停止!

这是我的代码:

int execute(char **args)
{   
    int i, in, out;
    char * inputF;
    char * outputF;
    if (args[0] == NULL) {
        return 1;
    }

    int pNum = 0;
    //char * cwd;
    //cwd = getcurDirectory();
    i = 0;
    printf("***Testing: Before while loop\n"); 
    while (args[i] != NULL) {
    printf("***Testing: entered while loop: %d\n", i); 
        if (strcmp(args[i], "<") == 0) {
            printf("***Testing: found %s in args[%d] \n", args[i], i); 
            in = 1;
            args[i] = NULL;
            inputF = args[i+1];
            args[i+1] = NULL;
            ++i;
            continue;
        }

        if (strcmp(args[i], ">") == 0) {
            printf("***Testing: found %s in args[%d] \n", args[i], i); 
            out = 1;
            args[i] = NULL;
            outputF = args[i+1];
            args[i+1] = NULL;
            ++i;
            continue;
        }

        if (strcmp(args[i], "|") == 0) {
            printf("***Testing: found %s in args[%d] \n", args[i], i); 
            ++pNum;
        }
        ++i;
    }

    if(in == 1 || out == 1){
        int pid = fork();
        if (pid == -1) {
                perror("fork");
        } else if (pid == 0) {   
            if (in) {
                int fd0 = open(inputF, O_RDONLY, 0);
                dup2(fd0, STDIN_FILENO);
                close(fd0);
                in = 0;
            }

            if (out) {
                int fd1 = creat(outputF, 0644);
                dup2(fd1, STDOUT_FILENO);
                close(fd1);
                out = 0;
            } 
            int r; 
            for(r = 0; r < sizeof(args); ++r)
                printf("***Testing: args[%d] %s \n", r, args[r]); 
            //setenv("parent",cwd,1);
            if(execvp(args[0], args) < 0 ){
                perror(*args);
                exit(EXIT_FAILURE);
            }
        } else {
            waitpid(pid, 0, 0);
            //free(args);
        }
    }

    if (pNum > 0){
        //printf("***Testing: Phew! got a pipe! \n");
        return handel_piping(args, pNum); 
    }

    for (i = 0; i < builtins(); i++) {
        if (strcmp(args[0], builtin_str[i]) == 0) {
            return (*builtin_func[i])(args);
        }
    }

    return launch_cmd(args);
} 

1 个答案:

答案 0 :(得分:1)

当您处理<>时,您的i还没有增加。由于这些后跟另一个参数,因此需要将i增加2而不是1,因此在处理下一个参数之前会跳过文件名。

    if (strcmp(args[i], "<") == 0) {
        printf("***Testing: found %s in args[%d] \n", args[i], i); 
        in = 1;
        args[i] = NULL;
        inputF = args[i+1];
        args[i+1] = NULL;
        i += 2;
        continue;
    }

    if (strcmp(args[i], ">") == 0) {
        printf("***Testing: found %s in args[%d] \n", args[i], i); 
        out = 1;
        args[i] = NULL;
        outputF = args[i+1];
        args[i+1] = NULL;
        i += 2;
        continue;
    }

另一个问题是您没有初始化inout。由于它们不太可能被初始化为0,因此代码的行为就像您键入了一个您没有重定向的重定向,然后使用未初始化的变量作为文件名。它们应该用以下内容初始化:

int i, in = 0, out = 0;

这个循环错了:

        for(r = 0; r < sizeof(args); ++r)
            printf("***Testing: args[%d] %s \n", r, args[r]); 

sizeof(args)是指针的大小,而不是args数组中元素的数量。并且它还尝试打印先前循环已替换为NULL的参数。它应该是:

        for(r = 0; args[r] != 0; ++r)
            printf("***Testing: args[%d] %s \n", r, args[r]);