簡體   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