C 如何对管道中的数据调用UNIX排序命令
我正在创建一个C程序,并用它在单独分叉的进程之间设置一个管道,用于进程间通信 第一个进程已将我需要的数据写入管道。 但是,当第二个进程从管道中读取数据时,我试图执行该进程,使其成为UNIX排序命令。我想对管道中的数据调用sort 我怎样才能在管道上呼叫分拣?在命令行上,我可以通过提供要排序的文件名作为命令行参数进行排序,例如“sort-r MyFileToSort”。我知道管道本质上被认为是文件,但它们只由文件描述符描述,据我所知,sort不知道如何处理fdC 如何对管道中的数据调用UNIX排序命令,c,unix,systems-programming,C,Unix,Systems Programming,我正在创建一个C程序,并用它在单独分叉的进程之间设置一个管道,用于进程间通信 第一个进程已将我需要的数据写入管道。 但是,当第二个进程从管道中读取数据时,我试图执行该进程,使其成为UNIX排序命令。我想对管道中的数据调用sort 我怎样才能在管道上呼叫分拣?在命令行上,我可以通过提供要排序的文件名作为命令行参数进行排序,例如“sort-r MyFileToSort”。我知道管道本质上被认为是文件,但它们只由文件描述符描述,据我所知,sort不知道如何处理fd 感谢您的帮助/反馈在这种情况下,您根
感谢您的帮助/反馈在这种情况下,您根本不需要传递
排序
任何参数来指定输入源或输出接收器。相反,在exec
ing它之前,您应该根据需要将管道的文件描述符附加到其stdin(FD 0,如果从管道接收数据)或stdout(FD 1,如果将数据写入管道)
请参阅dup2()
调用,该调用允许您为此目的设置要将FD复制到的目标。正如@JonathanLeffler所指出的,在调用exec之前,您需要确保关闭原始的FDs(将它们复制到您想要的号码之后)
由于您已在注释中阐明,您的目标是写入文件,因此在调用
exec
之前,您应该将FD 1附加到该目标文件,并将FD 0附加到包含输入的管道的输出端
int p[2];
if (pipe(p) != 0) ...report error and do not continue...
pid_t pid = fork();
if (pid < 0) ...report error, close pipe descriptors, and do not continue...
if (pid == 0)
{
/* Child - becomes sort */
dup2(p[0], 0);
close(p[0]);
close(p[1]);
int fd = open("output-file", O_CREAT | O_EXCL | O_WRONLY, 0644);
if (fd < 0) ...report error and exit...
dup2(fd, 1);
close(fd);
execlp("sort", "sort", (char *)0);
...report error and exit...
}
else
{
/* Parent - writes data to sort */
close(fd[0]);
...write data to fd[1]...
close(fd[1]);
int status;
int corpse;
while ((corpse = wait(&status)) > 0 && corpse != pid)
...consider reporting which child died...
...consider reporting sort status...
...continue with the rest of the program...
}
这通常是不必要的偏执(但尝试缺少标准I/O的程序可能会很有趣)。您已经尝试了什么?这可能会有所帮助:@martinclayton,为什么这里需要命名管道?您只需根据需要将
mkpipe()
返回的FD附加到stdin或stdout即可。@Charles help!=顺便说一下,@ Paulver,……顺便说一下,如果你不清楚如何设置这一点,你可以考虑阅读<代码> > Struts BASH-C 'GealTyPATA数据>排序> MyOutPutfile(),看看shell是如何完成任务的,并在pipe()
的两个文件描述符。谢谢,我将标准输入重定向到了管道的读取器,现在调用sort而不指定文件就可以了。我仍然有一个小问题,但是这个问题的上下文已经回答了谢谢你的代码示例。我认为sort必须显式地传递一个文件名,但我看到将stdin重定向到管道并只调用sort worksMany,但决不是all,Unix程序作为“过滤器”工作,在没有文件名的情况下读取标准输入并写入标准输出。您可以使用:execlp(“排序”、“排序”、“-o”、“输出文件”、(char*)0)代码>而不是在代码中执行I/O重定向。这会导致排序
写入输出文件
。通常,它允许sort
写入其一个输入文件;如果你接受了这个改变,你只是把这个选项当作一个副作用。如果你有排序选项,你应该考虑<代码> ExcVP()< <代码> > <代码>执行>(<)>代码>,而不是<代码> ExcLp()<代码>;您可以通过这种方式拥有可变长度的参数列表。
if (p[0] > FILENO_STDERR)
close(p[0]);