0

我正在尝试用c编写一个shell,除了grep之外它大部分都可以工作。每当我在 shell 中发出 grep 命令时,它就不会输出任何东西。这是我用来创建新子进程然后在其中运行 execvp() 的部分代码。

dup2 中的文件描述符(fd_in 和 fd_out)作为参数传递给具有此代码的函数。最有趣的是,当我输入 'grep' 或 'grep --help' 时,它会像往常一样显示。我错过了什么吗?或者必须用 grep 做一些特别的事情?

这就是我的 shell 发生的情况:从 bash 运行时的最后一个命令输出。

--> grep
Usage: grep [OPTION]... PATTERN [FILE]...
Try `grep --help' for more information.
--> wc /etc/hosts
 11  33 314 /etc/hosts
--> grep -i "perror" shell.c
--> 

这是代码:

void 
create_process(char *cmd_argv[], int fd_in, int fd_out, char *buffer_copy) {

    /*Flag bit for Background processes*/
    int FLAG = 0;

    pid_t cpid;
    int status;
    int i = 0,j = 0;

    /*Find the no. of arguments*/
    while(cmd_argv[j] != NULL)
        j++;

    /*Set the flag bit*/
    if(strcmp("&", cmd_argv[j-1]) == 0) {
        FLAG = 1;
        cmd_argv[j-1] = NULL;
    }

    //Create a child process
    cpid = fork();

    if (cpid == -1) {
        perror("fork");
        exit(EXIT_FAILURE);
    }

    //In the child...
    if (cpid == 0) {

    /*Checking if the file descriptors are already assigned*/

        /*For stdin*/
        if (fd_in != STDIN_FILENO) {
            dup2(fd_in, STDIN_FILENO);
            close(fd_in);
        }

        /*For stdout*/
        if (fd_out != STDOUT_FILENO) {
            dup2(fd_out, STDOUT_FILENO);
            close(fd_out);
        }

        /*Run the cmd specified*/
        status = execvp(cmd_argv[0], cmd_argv);

        /*In case of errors*/
        if(status < 0) {
            perror("execvp ");
            exit(1);
        }
    }

    //In the parent...
    else {

        if(FLAG == 1) {
            /*Find where the new bg process can be inserted*/
            while(1) {
                if (bgprocess[i].pid == 0) {
                    bgprocess[i].pid = cpid;
                    strcpy(bgprocess[i].cmd, buffer_copy);
                    break;
                }
                i++;
            }
            printf("[%d] : %s\n", cpid, cmd_argv[0] );
        }

        /*If not bg, wait for the process to exit*/
        else 
            waitpid(cpid, NULL, 0);
    }
}
4

2 回答 2

0

问题man dup2

从这些系统调用之一成功返回后,新旧文件描述符可以互换使用。它们引用相同的打开文件描述(参见 open(2))...</p>

因此,在您调用 dup2(您应该检查错误返回)之后,您关闭oldfd并且newfd因为它们是完全相同的描述符。

我无法弄清楚为什么grep --help完全有效,但您没有显示足够的代码来回答这个问题。

添加了以下评论:您仍然没有提供足够的代码。如果grep不工作比什么?wc /etc/hosts行得通吗?grep 没有什么特别之处,事实上它是一个完全不特殊的 Unix 过滤器。

于 2011-08-15T12:12:22.000 回答
0

问题是在你的 shell 中使用引号。Bash 在后台做了很多事情。grep -i perror shell.c 应该在您的 shell 上为您提供输出,无论从 bash 运行时的预期结果如何。

于 2011-08-16T13:43:37.513 回答