我们在 C 或 C++ 中是不是有类似于 IPC::Open3 的 perl
Posted
技术标签:
【中文标题】我们在 C 或 C++ 中是不是有类似于 IPC::Open3 的 perl【英文标题】:Do we have a anything similar to IPC::Open3 of perl in C or C++我们在 C 或 C++ 中是否有类似于 IPC::Open3 的 perl 【发布时间】:2018-01-18 08:29:09 【问题描述】:我使用 perl 的 open3 来运行命令,自定义命令的行为就像一个 shell,它接受输入并显示输出并等待另一个输入直到给出退出
现在我要使用相同的命令并用 C 语言编写它,我们是否有类似于 C 或 C++ 中的 IPC::Open3 的东西?
【问题讨论】:
pipe() 和 fork() 可以做同样的事情,但当然要麻烦得多。首先阅读Safe Pipe Opens in perldoc perlipc,这是对这些概念的比较高级的讨论。然后,您可以将相同的概念转移到 Posix/C。 是的,我在看管道和叉子,但我无法让它工作,而且它超出了我的理解范围,我想这需要一些时间来克服它 在 C 中还是在 C++ 中?这是不一样的。 Windows 还是 Linux? 简而言之:system
是最简单的,但可能不安全(并且不能提供Open3
的所有功能); popen
更好,还有fork
+exec
。我不确定“IPC::Open3”是否仅表示 Linux(不知道它是否可移植),但是:在 Windows 上有用于此的 API,首先是 CreateProcess,然后是 ShellExecute
(可能更多)
如果您可以使用boost
,那么boost::process
可能值得一看。
【参考方案1】:
popen() 支持单向通信。如果要双向数据交换,则需要 2 个管道。 Jeff Epler 提出了以下双向 popen2.c 实现:
#include <sys/types.h>
#include <unistd.h>
struct popen2
pid_t child_pid;
int from_child, to_child;
;
int popen2(const char *cmdline, struct popen2 *childinfo)
pid_t p;
int pipe_stdin[2], pipe_stdout[2];
if(pipe(pipe_stdin)) return -1;
if(pipe(pipe_stdout)) return -1;
printf("pipe_stdin[0] = %d, pipe_stdin[1] = %d\n", pipe_stdin[0], pipe_stdin[1]);
printf("pipe_stdout[0] = %d, pipe_stdout[1] = %d\n", pipe_stdout[0], pipe_stdout[1]);
p = fork();
if(p < 0) return p; /* Fork failed */
if(p == 0) /* child */
close(pipe_stdin[1]);
dup2(pipe_stdin[0], 0);
close(pipe_stdout[0]);
dup2(pipe_stdout[1], 1);
execl("/bin/sh", "sh", "-c", cmdline, 0);
perror("execl"); exit(99);
childinfo->child_pid = p;
childinfo->to_child = pipe_stdin[1];
childinfo->from_child = pipe_stdout[0];
return 0;
#define TESTING
#ifdef TESTING
int main(void)
char buf[1000];
struct popen2 kid;
popen2("tr a-z A-Z", &kid);
write(kid.to_child, "testing\n", 8);
close(kid.to_child);
memset(buf, 0, 1000);
read(kid.from_child, buf, 1000);
printf("kill(%d, 0) -> %d\n", kid.child_pid, kill(kid.child_pid, 0));
printf("from child: %s", buf);
printf("waitpid() -> %d\n", waitpid(kid.child_pid, NULL, 0));
printf("kill(%d, 0) -> %d\n", kid.child_pid, kill(kid.child_pid, 0));
return 0;
#endif
【讨论】:
虽然这些链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会失效。 格哈德·巴纳德,你的意思是什么? “Try popen()”是必不可少的部分。 :) 另外,我担心 popen() 规范不会很快发生重大变化,我不相信这些链接很快就会失效。至少在“学习者”有机会点击它们之前。无论如何,我希望所包含的示例不会引发更多的刻板反应。 感谢您的提醒,但我已经知道这一点,我正在寻找的可以被认为是双向通信,比如 popen2 提供输入和输出文件描述符?我想在 C 或 CPP 中没有这样的东西 @Laszlo,我们基于 SO 条款和条件进行审查,我们不发布仅链接的答案,并且由于仅链接的答案,该帖子最初被标记为低质量。如果您随后收到 4 次删除投票,它就会被删除,这就是为什么发布评论的原因。修改后应该没问题。 @learner,是的,您需要使用 2 个管道,因为它们是单向的。以上是关于我们在 C 或 C++ 中是不是有类似于 IPC::Open3 的 perl的主要内容,如果未能解决你的问题,请参考以下文章
Java是不是有类似IPC机制的Android Handler?