【问题标题】:My shell implementation overwriting when I don't want it to当我不希望它覆盖我的 shell 实现时
【发布时间】:2015-02-15 14:36:32
【问题描述】:

我目前有一个用 C 编写的 Bash 的基本实现。但是,当我尝试两次重定向标准输出时遇到了问题。以下是相关代码:

读取每个命令:

for ( ; ; ) {
        printf ("(%d)$ ", nCmd);                // Prompt for command
        fflush (stdout);
        if ((line = getLine (stdin)) == NULL)   // Read line
            break;                              //   Break on end of file

        list = lex (line);
        free (line);
        if (list == NULL) {
            continue;
        } else if (getenv ("DUMP_LIST")) {      // Dump token list only if
            dumpList (list);                    //   environment variable set
            printf ("\n");
        }

        cmd = parse (list);                     // Parsed command?
        freeList (list);
        if (cmd == NULL) {
            continue;
        } else if (getenv ("DUMP_TREE")) {      // Dump command tree only if
            dumpTree (cmd, 0);                  //   environment variable set
            printf ("\n");
        }

        process (cmd);                          // Execute command
        freeCMD (cmd);                          // Free associated storage
        nCmd++;                                 // Adjust prompt
    }

我们是我的代码的外壳部分搞砸了:

if (cmdList->type==SIMPLE)
    {
        pid_t fork_result;
            fork_result = fork();
            if (fork_result < 0) {
                fprintf(stderr, "Fork failure");
                exit(EXIT_FAILURE);
            }
            if (fork_result == 0) {
                if (cmdList->fromType==RED_IN)
                {
                    int fe = open(cmdList->fromFile, O_RDONLY, 0);
                    dup2(fe, 0);
                    close(fe);
                }
                if ((cmdList->toType==RED_OUT) || (cmdList->fromType==RED_APP))
                {
                    int fd = open(cmdList->toFile, O_CREAT | O_WRONLY, 0666);
                    dup2(fd, 1);
                    close(fd);
                }
                execvp(cmdList->argv[0],cmdList->argv);
                exit(EXIT_FAILURE);
            }
            else {
                int status;
                wait(&status);
            }

    }

当我阅读一个简单的命令时,这最后的 sn-p 代码完全按照我的意图工作。但是,当我使用 for 循环尝试重定向 stout 两次时,问题就出现了。例如,我尝试运行:

cat Tests/star.wars > +Bash.tmp
cat +Bash.tmp

cat Tests/stk.txt   > +Bash.tmp
cat +Bash.tmp

第一个命令将“ABC”写入 Bash.tmp。但是,当我运行第二个命令时,我希望它返回“DE”。但是,我得到“DEC”作为输出。怎么了?

【问题讨论】:

  • 你没有在open调用中使用O_TRUNC
  • 我应该这样做吗?我听说 O_WRONLY 应该可以解决问题。
  • O_WRONLY 是“只写”权限。 O_TRUNC 是在打开文件时截断文件的原因。
  • Bash shell 是一个庞大而复杂的代码库(具有许多超出 POSIX 所需的功能)。我认为说你正在实现一个 Unix 或 Bourne 兼容的 shell 会更正确。
  • 你的getLine() 只接受一个参数,所以它不是POSIX ssize_t getline(char **lineptr, size_t *n, FILE *stream);。你的如何工作?

标签: c linux shell stdout


【解决方案1】:

O_WRONLY 是“只写”权限。 O_TRUNC 是在打开文件时截断文件的原因。 – 伊坦·赖斯纳

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-22
    • 1970-01-01
    • 2019-04-25
    • 1970-01-01
    相关资源
    最近更新 更多