在 C 程序中执行程序
- 2024-11-04 08:43:00
- admin 原创
- 41
问题描述:
我应该如何在我的C
程序中运行另一个程序?我需要能够将数据写入STDIN
启动的程序(也许还可以从中读取STDOUT
)
我不确定这是否是标准 C 函数。我需要可以在 Linux 下运行的解决方案。
解决方案 1:
您想使用popen
。它为您提供了一个单向管道,您可以通过它访问程序的标准输入和标准输出。
popen 是现代 unix 和类 unix 操作系统的标准,其中 Linux 就是其中之一 :-)
类型
man popen
在终端上阅读更多相关信息。
编辑
是否popen
生成单向或双向管道取决于实现。在Linux和OpenBSD中,popen
生成只读或只写的单向管道。在OS X、FreeBSD和NetBSD popen
上生成双向管道。
解决方案 2:
不久前,我为其他人写了一些示例 C 代码,演示了如何执行此操作。下面是供您参考的:
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
void error(char *s);
char *data = "Some input data
";
main()
{
int in[2], out[2], n, pid;
char buf[255];
/* In a pipe, xx[0] is for reading, xx[1] is for writing */
if (pipe(in) < 0) error("pipe in");
if (pipe(out) < 0) error("pipe out");
if ((pid=fork()) == 0) {
/* This is the child process */
/* Close stdin, stdout, stderr */
close(0);
close(1);
close(2);
/* make our pipes, our new stdin,stdout and stderr */
dup2(in[0],0);
dup2(out[1],1);
dup2(out[1],2);
/* Close the other ends of the pipes that the parent will use, because if
* we leave these open in the child, the child/parent will not get an EOF
* when the parent/child closes their end of the pipe.
*/
close(in[1]);
close(out[0]);
/* Over-write the child process with the hexdump binary */
execl("/usr/bin/hexdump", "hexdump", "-C", (char *)NULL);
error("Could not exec hexdump");
}
printf("Spawned 'hexdump -C' as a child process at pid %d
", pid);
/* This is the parent process */
/* Close the pipe ends that the child uses to read from / write to so
* the when we close the others, an EOF will be transmitted properly.
*/
close(in[0]);
close(out[1]);
printf("<- %s", data);
/* Write some data to the childs input */
write(in[1], data, strlen(data));
/* Because of the small amount of data, the child may block unless we
* close it's input stream. This sends an EOF to the child on it's
* stdin.
*/
close(in[1]);
/* Read back any output */
n = read(out[0], buf, 250);
buf[n] = 0;
printf("-> %s",buf);
exit(0);
}
void error(char *s)
{
perror(s);
exit(1);
}
解决方案 3:
创建两个管道
pipe(...)
,一个用于stdin
,一个用于stdout
。fork(...)
該過程。在子进程(返回 0 的进程
fork(...)
)中,dup (...)
管道到stdin
/stdout
。exec[v][e]
子进程中要启动的程序文件。在父进程(
fork
)返回子进程的 PID 的进程)中执行循环,从子进程stdout
(select(...)
或poll(...)
,read(...)
)读取到缓冲区,直到子进程终止(waitpid(...)
)。最后,如果孩子有期望的话,就向他们提供输入
stdin
。当
close(...)
管道完工后。
解决方案 4:
对于简单的单向通信,popen() 是一个不错的解决方案。但是,对于双向通信,它毫无用处。
在我看来,imjorge(Jorge Ferreira)给出了双向沟通的大部分答案(80%?) - 但省略了一些关键细节。
至关重要的是,父进程关闭用于向子进程发送消息的管道的读取端。
至关重要的是,子进程关闭用于向子进程发送消息的管道的写入端。
至关重要的是,父进程关闭用于向父进程发送消息的管道的写入端。
至关重要的是,子进程要关闭用于向父进程发送消息的管道的读取端。
如果不关闭管道未使用的端,则当某个程序终止时,您将无法得到合理的行为;例如,子程序可能正在从其标准输入读取,但除非子程序中关闭管道的写入端,否则它将永远不会得到 EOF(读取到零字节),因为管道仍然打开,并且系统认为它有时可能会向该管道写入数据,即使它当前正挂起等待从中读取某些内容。
写入进程应该考虑是否处理在没有读取进程的管道上写入时发出的 SIGPIPE 信号。
您必须了解管道容量(取决于平台,可能只有 4KB)并设计程序以避免死锁。
解决方案 5:
您可以使用系统调用,阅读系统手册页(3)
解决方案 6:
我认为你可以使用
freopen
为了这 。
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件