我想打开一个bash应用程序(prog1)并使用C程序向该应用程序发送命令。 我尝试并编写了以下代码。
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
int main()
{
FILE * fp;
char message[10] = "command1\n";
fp = popen("sudo prog1","r");
write(STDIN_FILENO, message, 10);
pclose(fp);
execlp("sudo prog1", "sudo prog1", "-l", NULL);
return 0;
}
此代码提供输出:
Linux:~$ ./ prog 2 // running the code
command // prints "command"
prog1-> // Then opens "prog1" (prog1 waits for user commands)
但我希望它是
Linux:~$ ./ prog 2 // running the code
prog1-> command // open "prog1" and write command (instead of getting it from user)
退出 prog1 后或在开始 prog1 之前写入。请让我知道如何编写&#34;命令&#34;打开应用程序 prog1 后,在 prog1 中。谢谢。
注意:如果我做
fp = popen("sudo prog1","w"); //to write
它会抛出以下错误 tcgetattr:设备不适当的ioctl
答案 0 :(得分:3)
您的主要错误是认为popen()以某种方式将您的子进程与您的STDIN_FILENO相关联。它没有。 STDIN_FILENO与您的“sudo prog1”孩子无关。你必须创建一个管道,将描述符复制到stdin / stdout,并使用fork + exec来做到这一点。但你使用popen()所以不要这样做。
相反,你应该从fp写作和阅读。
类似的东西:
fprintf(fp, message);
fgets(response, 100, fp);
由于fprintf()是缓冲的,你应该在行尾使用\ n,或者fflush()。
另外,当你已经调用了popen()时,最后使用exec / execlp是没有意义的。看起来您可能正在混合两种您通过示例看到的方法。
popen()实际上是(pipe,dup stdin / stdout / stderr,fork,execl)的组合来处理将子进程重定向到连接到父进程的文件流。因此,除非您需要与popen()不同的语义,否则无需重新实现。
您在技术上正在实现“期望”功能,因此您可能希望研究期望或期望不同语言的模块。 Expect包含在Linux发行版中,但通常是可选的。
http://expect.sourceforge.net/
http://search.cpan.org/~rgiersig/Expect-1.21/Expect.pod
更不用说,Perl已经有了一个Sudo模块。