【发布时间】:2011-02-06 00:02:51
【问题描述】:
我正在编写一个 C 程序,其中我有 fork()、exec() 和 wait()。我想将我执行的程序的输出写入文件或缓冲区。
例如,如果我执行ls,我想将file1 file2 etc 写入缓冲区/文件。我认为没有办法读取标准输出,这是否意味着我必须使用管道?这里有没有我找不到的通用程序?
【问题讨论】:
我正在编写一个 C 程序,其中我有 fork()、exec() 和 wait()。我想将我执行的程序的输出写入文件或缓冲区。
例如,如果我执行ls,我想将file1 file2 etc 写入缓冲区/文件。我认为没有办法读取标准输出,这是否意味着我必须使用管道?这里有没有我找不到的通用程序?
【问题讨论】:
您也可以使用 linux sh 命令并传递一个包含重定向的命令:
string cmd = "/bin/ls > " + filepath;
execl("/bin/sh", "sh", "-c", cmd.c_str(), 0);
【讨论】:
你需要明确地决定你想做什么——最好解释得更清楚一点。
如果您知道要执行命令的输出到哪个文件,那么:
如果您希望父级读取子级的输出,请安排子级将其输出通过管道传回父级。
【讨论】:
用于将输出发送到另一个文件(我省略了错误检查以专注于重要细节):
if (fork() == 0)
{
// child
int fd = open(file, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
dup2(fd, 1); // make stdout go to file
dup2(fd, 2); // make stderr go to file - you may choose to not do this
// or perhaps send stderr to another file
close(fd); // fd no longer needed - the dup'ed handles are sufficient
exec(...);
}
用于将输出发送到管道,以便您可以将输出读入缓冲区:
int pipefd[2];
pipe(pipefd);
if (fork() == 0)
{
close(pipefd[0]); // close reading end in the child
dup2(pipefd[1], 1); // send stdout to the pipe
dup2(pipefd[1], 2); // send stderr to the pipe
close(pipefd[1]); // this descriptor is no longer needed
exec(...);
}
else
{
// parent
char buffer[1024];
close(pipefd[1]); // close the write end of the pipe in the parent
while (read(pipefd[0], buffer, sizeof(buffer)) != 0)
{
}
}
【讨论】:
select,最后在孩子身上使用waitpid 来移除僵尸?
因为您看起来要在 linux/cygwin 环境中使用它,所以您想使用 popen。这就像打开一个文件,只有你会得到执行程序stdout,所以你可以使用你正常的fscanf、fread等。
【讨论】:
fork 后,使用dup2(2) 将文件的 FD 复制到 stdout 的 FD 中,然后执行。
【讨论】: