[英]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
替換當前進程,它將永遠不會返回。
您有多個問題:
一個問題是您對close()
調用太少了。 當您使用dup2()
將文件描述符從管道復制到標准輸入或標准輸出時,應關閉pipe()
返回的兩個文件描述符。
第二個問題是外殼程序刪除了參數周圍的雙引號,但是您已經在參數周圍添加了雙引號。 您正在尋找名稱包含".c"
文件(其中雙引號是所搜索文件名的一部分)。 采用:
char *grep[] = { "grep", "\\\\.c$", NULL };
這會在行尾查找一個點和一個c
。
您應該在execvp()
之后報告失敗。 如果任何exec*()
函數返回,則失敗。 例如,當用戶鍵入錯誤的命令名稱時,可能會發生這種情況。 報告錯誤,然后子進程退出,這一點至關重要。 如果您不這樣做,那么您可能會遇到一個普通的迭代外殼程序(而不是這種單發,非迭代,非交互的外殼程序),並且所有外殼程序進程都試圖同時從終端讀取數據,導致混亂和混亂。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.