微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用pipe道运行命令?

我正在尝试使用execvp来运行ls | wc。 所以我创build一个pipe道,然后叉子创build一个孩子。 我closures父/子适当的(read./write)结束,然后将另一端映射到标准输出/标准input。 然后我在父亲中使用execvp和wc在子代中运行ls。 当我运行该程序时,它说

wc:standard input:bad file descriptor. 0 0 0 wc: -:Bad file descriptor

这是我的代码

int main() { //int nbBytes = 0; //stream length int pfd_1[2]; //file descriptor //char buffer[MAX_FILE_LENGTH]; char* arg[MAX_FILE_LENGTH]; pid_t processpid; //Create a pipe if(pipe(pfd_1) == -1) { printf("Error in creating pipe"); return 0; } //Create a child processpid = fork(); if(processpid == -1) { printf("Erro in fork"); exit(1); } else if(processpid == 0) //Child { //redirect read end file descriptor to standard input dup2(pfd_1[0],0); //Close the write end if(close(pfd_1[1] == -1)) { printf("Error in closing the write end file descriptor"); exit(1); } arg[0] = "wc"; //arg[1] = "-l"; arg[1] = ''; if(execvp(arg[0],arg) == -1) { printf("Error in executing ls"); } } else //Parent { //redirect standard output to the file descriptor dup2(pfd_1[1],1); //Close the read end if(close(pfd_1[0] == -1)) { printf("Error in closing the read end from parent"); exit(1); } //Command arg[0] = "ls"; arg[1] = "/proc/1/status"; arg[2] = ''; if(execvp(arg[0],arg) == -1) { printf("Error in executing ls"); } }

}

任何想法可能是错的? 为什么会认为标准input是坏的文件描述符? 我的理解是,因为stdin和读取结束文件描述符是别名,所以wc -l会读取父进程的输出。 我需要做scanf从标准input读取吗?

确定可读文件描述符是否是pipe道的读取结束

MSYS shell保持脚本文件打开,防止修改

lsof没有给内置的阅读bash o / p

在STDOUT和STDIN的文件描述符上执行库函数的奇怪行为

寻找一个进程的Linux(C代码)打开文件描述符?

Windows中的socket和HANDLE有什么区别?

将stderrredirect到从python exec-ed进程的标准输出

在Linux平台上使用套接字时是否有文件描述符泄漏?

为什么UNIX文件描述符不是由它们自己的types实现的,特别是在C ++中?

处理结束后`/ dev / ttyS *`上的QSerialPort效应?

问题在于这一行:

if(close(pfd_1[1] == -1))

您正在关闭pfd_1[1] == -1 ,这必然等于0 (因为它们永远不会相等)。 正确的行可能是:

if (close(pfd_1[1]) == -1)

请注意,稍后您将再次尝试关闭父进程中的读取结束。

如果你要fork孩子,你必须在父进程中调用wait()以避免“僵尸”子进程。 所以你不想覆盖原始进程通过exec与另一个可执行文件分叉的父进程。

以您想要的方式设置一系列管道的一种快速方法是为每个要运行的可执行文件分配一个文件,然后将这些数据读回到父文件的缓冲区中。 然后,将来自第一个孩子的数据馈送到父母分岔的新的子进程中。 所以每个孩子都从父母那里得到数据,处理数据,并将数据写回到父进程,父进程将转换后的数据存储在缓冲区中。 然后该缓冲区被送到下一个孩子等等。缓冲区中数据的最终结果是管道的最终输出

这里有一个代码

//allocate buffer unsigned char buffer[SIZE]; for (each executable to run in pipeline) { pipes[2]; pipe(pipes); pid_t pid = fork(); if (pid == 0) { //setup the pipe in the child process //call exec } else { //setup the pipe in the parent process if (child executable is not the first in the pipeline) { //write contents of buffer to child process } //read from the pipe until the child exits //store the results in buffer //call wait,and maybe also check the return value to make sure the //child returned successfully wait(NULL); //clean up the pipe } }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐