我有一个运行bc
至popen()
的代码。我可以拦截计算器的输出并在其前面添加"输出="文本。但是,如何拦截用户写入bc
的内容?
#include <stdio.h>
#include <stdlib.h>
int main(void) {
FILE *in;
char buff[512];
if(!(in = popen("bc", "r"))){
exit(1);
}
while(fgets(buff, sizeof(buff), in)!=NULL){
printf("Output = %s", buff);
}
pclose(in);
return 0;
}
答案 0 :(得分:0)
您可以将bc
和echo
与管道合并:echo '12*4' | bc
输入12*4
的示例:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void) {
FILE *in;
char buff[512];
char cmd[512];
while (fgets(buff, sizeof(buff), stdin)!=NULL){
strcpy(cmd, "echo '");
strcat(cmd, buff);
strcat(cmd, "' | bc");
if(!(in = popen(cmd, "r"))){
exit(1);
}
fgets(buff, sizeof(buff), in);
printf("output:%s", buff);
}
pclose(in);
return 0;
}
输出:
david@debian:~$ ./demo
12*4
output:48
答案 1 :(得分:0)
您需要使用pipe()
和fork/exec()
。但是,手动管道非常复杂:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void) {
int write_pipe[2], read_pipe[2];
pipe(read_pipe); pipe(write_pipe);
#define PARENT_READ read_pipe[0]
#define CHILD_WRITE read_pipe[1]
#define CHILD_READ write_pipe[0]
#define PARENT_WRITE write_pipe[1]
int child = fork();
if (child == 0) { /* in child */
close(PARENT_WRITE);
close(PARENT_READ);
dup2(CHILD_READ, 0); close(CHILD_READ);
dup2(CHILD_WRITE, 1); close(CHILD_WRITE);
execl("/usr/bin/bc", "/usr/bin/bc");
} else { /* in parent */
close(CHILD_READ);
close(CHILD_WRITE);
write(PARENT_WRITE, "2+3\n", 4);
char buff[512];
int output_len=read(PARENT_READ, buff, sizeof(buff));
write(1, buff, output_len);
close(PARENT_READ);
}
return 0;
}
答案 2 :(得分:0)
您要做的是启动子流程,然后同时启动:
允许您等待两个句柄上的活动的系统调用称为poll,但在我们这样做之前,我们需要创建句柄并启动子进程:
int a[2], b[2];
if(pipe(a)==-1)abort(); // for communicating with subprocess input
if(pipe(b)==-1)abort(); // for communicating with subprocess output
switch(fork()) {
case -1: abort();
case 0: dup2(a[0],0), dup2(b[1],1), execlp("/usr/bin/bc", "bc", 0); exit(1);
};
注意pipe的工作原理:写入fildes [1]的数据出现在(即可以读取)fildes [0]上。这意味着我们想从标准中读取输出我们的子进程b[0]
并写入子进程a[1]
的标准输入。
在我们这样做之前,我们可以使用poll指令等待标准输入(fd#0)或子进程输出(b [0])上的活动:
for(;;) {
struct pollfd p[2]={0};
p[0].fd = 0; p[1].fd = b[0];
p[0].events = p[1].events = POLLIN;
while (poll(p,2,-1) <= 0);
此时,至少有一个文件描述符存在活动。您可以通过检查.revents
成员来查看哪一个。
if(p[0].revents & POLLIN) {
r = read(0, buffer, sizeof(buffer));
write(a[1], buffer, r); // check for errors, or perhaps modify buffer
}
if(p[1].revents & POLLIN) {
r = read(b[0], buffer, sizeof(buffer));
write(1, buffer, r); // check for errors, or perhaps modify buffer
}
特别注意我们使用成员a[1]
和b[0]
中的成员}
和read()
到子进程标准输入(0)和标准输出(1)。
此时你可以循环回来再次轮询:
0
断开连接(如EOF,程序崩溃等)将显示为break;
返回<!-- Mobile Links -->
<a href="#" id="mobile-menu-icon" class="mobile-menu-icon show-for-custom-down" title="<?php esc_attr_e('Mobile Menu', 'punjaban' ); ?>"><span class="lines"></span></a>
<a href="#" class="mobile-search-icon" title="<?php esc_attr_e('Search', 'punjaban' ); ?>">
</a>
<!-- Mobile Menu -->
<?php
register_nav_menus( array(
'mobile-primary-menu' => 'Mobile Navigation Menu',
) );
wp_nav_menu( array( 'theme_location' => 'primary', 'container_class' => 'mobile-primary-menu' ) ); ?>
,因此请仔细观察此情况,如果需要请注意<!-- Mobile Links -->
<a href="#" id="mobile-menu-icon" class="mobile-menu-icon show-for-custom-down" title="Mobile Menu"><span class="lines"></span></a>
<a href="#" class="mobile-search-icon" title="Search">
</a>
<!-- Mobile Menu -->
<div class="mobile-primary-menu"><ul id="menu-primary-menu" class="menu"><li id="menu-item-21" class="search-icon menu-item menu-item-type-custom menu-item-object-custom menu-item-21"><a rel="nofollow" href="#">Search</a></li>
<li id="menu-item-407" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-407"><a rel="nofollow" href="/shop">SHOP</a></li>
<li id="menu-item-239" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-239"><a rel="nofollow" href="/recipes">RECIPES</a></li>
<li id="menu-item-17" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-17"><a rel="nofollow" href="/stockist">STOCKISTS</a></li>
<li id="menu-item-598" class="fourth-child menu-item menu-item-type-post_type menu-item-object-page menu-item-598"><a rel="nofollow" href="http://www.punjaban.co.uk/our-story/">OUR STORY</a></li>
<li id="menu-item-19" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-19"><a rel="nofollow" href="/blog">BLOG</a></li>
<li id="menu-item-300" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-300"><a rel="nofollow" href="http://www.punjaban.co.uk/contact/">CONTACT</a></li>
</ul></div>
。