C popen()备选方案
我的问题是这个问题的延伸: 动机: 1) 我的程序需要在一个文件上创建一个子文件,该子文件不包含C popen()备选方案,c,exec,process,popen,C,Exec,Process,Popen,我的问题是这个问题的延伸: 动机: 1) 我的程序需要在一个文件上创建一个子文件,该子文件不包含tail。我需要逐行处理输出。这就是为什么我使用popen,因为它返回文件*。我可以很容易地提取单行,做我需要做的事情并打印出来 popen的一个问题是您没有得到child的pid(在我的例子中是tail命令) 2) 我的程序不应在其子程序完成之前退出。所以我需要做等待;但是没有pid,我就做不到 我如何实现这两个目标 一个可能的解决方案是:执行execvp(“tail-f file>tmpfile”
tail
。我需要逐行处理输出。这就是为什么我使用popen
,因为它返回文件*。我可以很容易地提取单行,做我需要做的事情并打印出来
popen的一个问题是您没有得到child的pid(在我的例子中是tail命令)
2) 我的程序不应在其子程序完成之前退出。所以我需要做等待
;但是没有pid,我就做不到
我如何实现这两个目标
一个可能的解决方案是:执行execvp(“tail-f file>tmpfile”)并继续读取该tmpfile。不过,我不确定这个解决方案有多好。您可以使用
wait
,因为它不希望等待PID,而只是等待任何子进程退出。如果您创建了其他子进程,您可以跟踪它们,如果wait
返回未知的PID,您可以假定它来自popen
进程。我不确定您为什么需要子进程ID。当子项退出时,管道读取将返回EOF。如果需要终止子级,只需关闭管道
pipe
,这是exec*
系列的一个函数和fdopen
。这是非标准的,但popen也是EOF
execvp(“tail-f file>tmpfile”)
不起作用,重定向是shell的一个功能,您没有在这里运行shell。即使成功了,这也是一个糟糕的解决方案。假设您已读取到文件的末尾,但子进程尚未结束。你是做什么的为什么不使用pipe/fork/exec方法
pid_t pid = 0;
int pipefd[2];
FILE* output;
char line[256];
int status;
pipe(pipefd); //create a pipe
pid = fork(); //span a child process
if (pid == 0)
{
// Child. Let's redirect its standard output to our pipe and replace process with tail
close(pipefd[0]);
dup2(pipefd[1], STDOUT_FILENO);
dup2(pipefd[1], STDERR_FILENO);
execl("/usr/bin/tail", "/usr/bin/tail", "-f", "path/to/your/file", (char*) NULL);
}
//Only parent gets here. Listen to what the tail says
close(pipefd[1]);
output = fdopen(pipefd[0], "r");
while(fgets(line, sizeof(line), output)) //listen to what tail writes to its standard output
{
//if you need to kill the tail application, just kill it:
if(something_goes_wrong)
kill(pid, SIGKILL);
}
//or wait for the child process to terminate
waitpid(pid, &status, 0);
如果在某些错误的情况下,我需要杀了孩子,我可以这样做吗?(这种情况首先出现了吗?),我只是想大声说出来。假设程序中发生了错误,它必须退出,那么
等待确保在退出主程序之前也杀死/终止子程序吗?您可以,然后只需调用kill(getpgrp(),SIGTERM)
将终止所有进程。子进程可以是“tail-f”,永远不会返回。在这种情况下,当我执行ctrl-C时,在我的主程序退出之前,我希望完成子项“tail-f”。1。它们不是非标准的,只是在C标准之外。它们是POSIX标准的一部分。在结束阅读后是否需要关闭(pipefd[0])
?或者就在kill
之前?顺便说一句,如果您使用GLib,它有一个预烘焙的实现,具有大量的功能,另外它还处理所有错误代码等等。请参阅(免责声明:我多年前就实现了此功能)@havoc或libHX的HXproc_*函数族,它不使用像glib那样有那么多参数的函数。当然,只要提到我知道的库就可以了。