对 Unix 中 exec(family) 的使用感到困惑
Posted
技术标签:
【中文标题】对 Unix 中 exec(family) 的使用感到困惑【英文标题】:Confused on the use of exec(family) in Unix 【发布时间】:2012-09-21 05:29:52 【问题描述】:我正在编写一个程序,在该程序中我使用系统调用 fork() 创建一个子进程,然后创建一个孙子进程,以及在子进程和孙子进程之间创建一个管道。我认为我的实现相当不错,但是当我运行程序时,它只是直接跳过了我代码中的提示。
基本上我们有这个:
-进程开始 fork() 创建子 孩子创建管道 Fork() 创建孙子,管道继承。
TL;DR- 代码跳过 UI 提示,不确定我是否正确输入数据,不确定我是否正确将数据读入进程。
如何读取管道中的输入?
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
void main(int argc, char *argv[])
int p[2];
int pid, pid2;
pid = fork();
if(pid == 0)
pipe(p);
pid2 = fork();
switch(pid2)
case -1:
printf("CASE 1");
exit(-1);
case 0:
close(0);
dup(p[0]);
close(p[0]);
close(p[1]);
execl("./Sort/sort", 0);
break;
default:
close(1);
dup(p[1]);
close(p[1]);
close(p[0]);
execl("./Pre/pre", 0);
break;
else
wait(pid);
printf("Process Completed\n");
exit(0);
pre 的子进程:
#include <stdio.h>
void main (int argc, char *argv[])
char n1[20];
int g1;
FILE *ofp, *ifp;
int track;
ofp = fopen("output.txt", "w");
while(track != -1)
printf("Please enter the student's grade and then name, ");
printf("separated by a space: ");
scanf("%3d %s", &g1, n1);
if (g1 >= 60)
fprintf(ofp, "%s\n", n1);
printf("Add another name?(-1 to quit, 0 to continue): ");
scanf("%d", &track);
fclose(ofp);
ifp = fopen("output.txt", "r");
printf("Students that made a 60+:\n");
while(fscanf(ifp, "%s", n1) == 1)
printf("%s\n", n1);
fclose(ifp);
排序的子进程:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int stringcmp(const void *a, const void *b)
const char **ia = (const char **)a;
const char **ib = (const char **)b;
return strcmp(*ia, *ib);
void main(int argc, char *argv[])
int i = 0;
int num = 0;
int j = 0;
char name[20];
printf("How many names would you like to enter? ");
scanf("%d", &num);
char **input = malloc(num * sizeof(char*));
for (i=0; i < num; i++)
printf("Please input a name(first only): ");
scanf("%s", name);
input[i] = strdup(name);
qsort(input, num, sizeof(char *), stringcmp);
printf("Names:\n");
for(j = 0; j < num; j++)
printf("%s\n", input[j]);
for( i = 0; i < num; i++ ) free(input[i]);
free(input);
【问题讨论】:
请添加子进程的来源,这样更容易重现行为 【参考方案1】:观察pre
将提示输出到标准输出。该文本将最终出现在管道中,最终将出现在 sort
的 stdin
中。
您应该将所有提示fprintf
发送到stderr
。
pre
也不以sort
所期望的格式输出文本; sort
需要一个整数 n
后跟 n
单词(名字)。所以,这应该是pre
在stdout
上输出的唯一 文本;其他一切都需要转到文件或stderr
。
附:此外,请使用dup2(p[0], 0)
而不是close(0); dup(p[0])
,因为它可以使您的意图更清晰,并可能避免线程问题(当然只有在您有线程时才相关,但值得牢记)。
【讨论】:
感谢 dup 提示,我的教授只是按照我实施的方式解释过它。至于将所有提示打印到stderr,是否更容易完全删除提示,并将预读的输出直接读入排序?或者这会导致问题吗? 是的,除非您想要某种交互模式,否则我看不出提示的充分理由。如果您删除提示与将提示推送到标准错误,那么功能上应该没有区别。 完美。这就是我感到困惑的地方。我不确定是否必须有提示才能与管道交互,尽管在输入该语句时,我觉得这样想很愚蠢! :P 好吧,如果您想与pre
交互交互(可能通过sort
),那么提示很有用。但我同意@Michael 的观点:它们并不重要。
最后一个问题:fscanf 和 fprintf 是否应该分别改为 scanf/printf?或者输出(由于关闭/重复)是否会更改为管道?【参考方案2】:
这里有两个例子说明如何做到这一点
-
http://www.gnu.org/software/libc/manual/html_node/Creating-a-Pipe.html
http://tldp.org/LDP/lpg/node11.html
编辑:我可以看出您正在尝试将“./Pre/pre”的输出通过管道传输到“./Sort/sort”的输入,但我不确定“代码跳过 UI”是什么意思提示”,因为对于 case 1:
和 default:
,您没有任何提示。究竟是什么问题?如果您想要更具体的内容,请在您的问题中解释更多详细信息。
【讨论】:
本质上,我正在使用 execl 来调用我已经编写的两个程序。当它启动时,我将一个文本文件自动读入“pre”调用(默认开关)。问题是,我不确定他们应该如何进行管道转换,以便为管道末端的“排序”调用提供足够的数据。 pre 的数据输出是否必须以某种方式构造以便 sort 正确处理?编辑:我在编写当前代码时实际上使用了这两个网站作为参考:P以上是关于对 Unix 中 exec(family) 的使用感到困惑的主要内容,如果未能解决你的问题,请参考以下文章
使用 FIND 和 EXEC 对多个文件执行文件名要求的 Perl 脚本