【问题标题】:redirection output to a file gives encoding issue in C将输出重定向到文件会导致 C 中的编码问题
【发布时间】:2016-07-13 17:03:00
【问题描述】:

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

  • 如果我将此命令输入到我的程序“sort ”中,我得到的文件的名称是“`b” " 虽然它不应该写入文件!并且程序挂起并且没有排序输出!

  • 如果我输入:“ls > out.txt”,输出会同时写入终端和 out.txt 文件

    李> 1234563然后它就停止了!

这是我的代码:

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);
} 

【问题讨论】:

  • for(r = 0; r &lt; sizeof(args); ++r) 是错误的。 args 是指针,而不是数组,所以 sizeof(args) 是指针中的字节数(通常为 4 或 8,具体取决于架构)。
  • 警告:inout 似乎没有初始化。
  • @purplepsycho 感谢您的提示,感谢您,我在我的解决方案中考虑了它们,但我仍然遇到我在帖子中提到的相同问题。还有其他提示吗?

标签: c shell redirect


【解决方案1】:

当您处理 &lt;&gt; 时,您增加的 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]); 

【讨论】:

  • 这些是很好的提示,非常感谢!但是,我仍然有上面提到的相同问题,我无法弄清楚问题出在哪里:\
  • 我想不出你在终端重定向到文件时看到输出的任何原因。
  • 如果不使用像tee 这样的程序,这是不可能发生的。
  • 我不会为你调试一个 400 行的程序。你有一个调试器,学会使用它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-11
  • 1970-01-01
  • 2013-04-21
相关资源
最近更新 更多