所以我有一個練習要做,這個練習的一部分要求我們執行一個作為引數傳遞的命令,能夠在標準輸入上傳遞一些字串,并在標準輸出和標準錯誤上得到它的輸出。我是怎么做到的,我需要將 stdout 和 stderr(孩子的,它將呼叫一個 exec)重定向到幾個管道(管道的另一端由父級保持打開)。我設法做到了,當我要求它執行 bash 并發送它“ls”時,它給了我我想要的東西,我想要的地方。與貓和其他人一樣。問題是,當我嘗試執行 awk 或 sed 時,管道上沒有寫入任何內容。曾經。如果我保持標準輸出不變,它會按應有的方式列印它。但是一旦我重定向標準輸出,什么都沒有。我嘗試了所有方法,select()、wait()、sleep()(即使不允許這樣做)。似乎沒有任何效果。
我為我的意思做了一個最低限度的作業示例(顯然,它缺乏約定和謹慎的寫作,如 free() 和 close(),但它確實是作業),這是我所附的。當我這樣稱呼它時,代碼可以作業:
./program $(which bash)
它提示輸入一些東西,我寫“ls”,它給了我預期的結果,但是當我嘗試時,
./program $(which awk) '{print $0;}'
我什么也沒得到
這是代碼(最小作業示例):
#define _GNU_SOURCE
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <signal.h>
#include <errno.h>
int main(int argc, char* argv[]){
int fdStdinP[2],fdStdoutP[2];
char *string,*array[3];
array[0]=argv[1];
array[1]=argv[2];
array[2]=0;
pipe(fdStdinP);
pipe(fdStdoutP);
int pid=fork();
if(pid==0){
close(fdStdinP[1]);
close(fdStdoutP[0]);
dup2(fdStdinP[0],0);
close(fdStdinP[0]);
dup2(fdStdoutP[1],1);
close(fdStdoutP[1]);
//as suggested, the file descriptors are now closed
execvp(argv[1],array);
perror("");
return 0;
}
close(fdStdinP[0]);
close(fdStdoutP[1];
string=calloc(1024,sizeof(char));
read(0,string,1024);
write(fdStdinP[1],string,1024);
free(string);
string=calloc(1024,sizeof(char));
read(fdStdoutP[0],string,1024);
printf("I have read:%s",string);
return 0;
}
感謝您的時間。
uj5u.com熱心網友回復:
awk 繼續等待輸入并緩沖其輸出,因此似乎掛起。關閉發送端將告訴 awk 它的輸入已經結束,因此它將結束并重繪 其輸出。
write(fdStdinP[1],string,1024);
close(fdStdinP[1]); // just added this line.
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/485432.html
下一篇:計算哈希表大小的正確方法是什么
