繁体   English   中英

ls | 用C编写的shell中的grep

[英]ls | grep in shell written in C

我试图用C制作自己的shell。它使用一个管道,并且输入(目前)是静态的。 我使用execvp执行命令。 一切正常,除了运行命令ls |grep ".c"没有任何结果。 谁能告诉我问题出在哪里并找到解决方案。

到目前为止的外壳:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>

int   p[2];
int pid;
int r;

main()
{
    char *ls[] = {"ls", NULL};
    char *grep[] = {"grep", "\".c\"", NULL};

    pipe(p);

    pid = fork();
    if (pid  != 0) {
            // Parent: Output is to child via pipe[1]

            // Change stdout to pipe[1]
            dup2(p[1], 1);
            close(p[0]);

            r = execvp("ls", ls);
    } else {
            // Child: Input is from pipe[0] and output is via stdout.
            dup2(p[0], 0);
            close(p[1]);

            r = execvp("grep", grep);
            close(p[0]);
    }

    return r;
}

删除grep参数中的引号。 即使用

char *grep[] = {"grep", ".c", NULL};

如果您正在调用execvp ,则不会发生参数的常规shell扩展(即,globbing,引号的删除等),因此实际上您所做的与

ls | grep '".c"'

在普通外壳中。

另请注意,对execvp的调用之后不会执行任何操作, execvp 替换当前进程,它将永远不会返回。

您有多个问题:

  1. 一个问题是您对close()调用太少了。 当您使用dup2()将文件描述符从管道复制到标准输入或标准输出时,应关闭pipe()返回的两个文件描述符。

  2. 第二个问题是外壳程序删除了参数周围的双引号,但是您已经在参数周围添加了双引号。 您正在寻找名称包含".c"文件(其中双引号是所搜索文件名的一部分)。 采用:

     char *grep[] = { "grep", "\\\\.c$", NULL }; 

    这会在行尾查找一个点和一个c

  3. 您应该在execvp()之后报告失败。 如果任何exec*()函数返回,则失败。 例如,当用户键入错误的命令名称时,可能会发生这种情况。 报告错误,然后子进程退出,这一点至关重要。 如果您不这样做,那么您可能会遇到一个普通的迭代外壳程序(而不是这种单发,非迭代,非交互的外壳程序),并且所有外壳程序进程都试图同时从终端读取数据,导致混乱和混乱。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM